On this page
- Origin and adoption
- How TCC works
- Phase 1 — Try (Reserve)
- Phase 2a — Confirm (Commit)
- Phase 2b — Cancel (Rollback)
- TCC vs Two-Phase Commit (2PC)
- TCC vs Saga Pattern
- Three design hazards and their solutions
- 1. Empty Rollback
- 2. Suspension / Hanging Transaction
- 3. Idempotency
- Ecommerce use cases
- Inventory reservation for flash sales
- Order + payment + accounting (core settlement)
- Alipay escrow example
- Payment authorisation in ecommerce checkout
- Frameworks and implementations
- Performance characteristics
- TCC variants
- Asynchronous Guaranteed TCC
- Compensated TCC
- When to use TCC
- Key terms
- Next frontier concepts
TCC (Try-Confirm-Cancel)
TCC (Try-Confirm-Cancel)
TCC (Try-Confirm-Cancel) is a distributed transaction pattern that coordinates multiple services by reserving resources in a first phase before committing or rolling back — avoiding the blocking locks of Two-Phase Commit (2PC) while providing stronger consistency guarantees than the Saga Pattern. It originated at Ant Financial / Alipay and is the dominant distributed transaction pattern for high-performance ecommerce platforms in the Alibaba ecosystem.
Origin and adoption
- TCC was contributed to the Apache Seata project (formerly Fescar) by the Ant Financial / Alipay engineering team. (Apache Seata blog, 2019 [PRE-2024])
- Seata describes TCC as "initially contributed by Ant Financial." (Apache Seata user docs, v2.6, 2024)
- Atomikos notes that TCC "is really popular in China, where they have different channels and less influence from the West" — explaining higher TCC adoption in Chinese internet platforms than in Western microservices discourse. (Atomikos blog [PRE-2024])
- Western cloud providers (AWS, Azure, Temporal) do not document TCC as a named first-class pattern; they default to Saga Pattern + Compensating Transaction approaches. (AWS Architecture blog, Azure Architecture Center, Temporal docs — searched 2026-08-29)
- Oracle MicroTx (Release 24.2, 2024-11-27) is the most complete Western primary-source implementation of TCC, using a REST/HTTP protocol model.
How TCC works
TCC splits a distributed transaction across three explicit phases — each implemented in business code by every participating service:
Phase 1 — Try (Reserve)
- Each participant service checks whether it can fulfil its part of the transaction and reserves the required resources in an intermediate state.
- Resources are not committed; they are "soft-locked" at the application level. For example: available stock is reduced and placed in a "reserved" quantity column; funds are moved from "available" to "frozen" — not deducted. (Apache Seata blog [PRE-2024]; ddhigh.com [PRE-2024])
- "The Try operation is the first phase, responsible for checking and reserving resources." (Apache Seata [PRE-2024])
- Oracle MicroTx maps the Try phase to an HTTP POST call: the initiator POSTs to each participant to create a reservation; each participant returns a reservation URI. (Oracle MicroTx docs, 2024-11-27)
- The transaction coordinator collects all accepted reservation URIs during this phase. (Oracle MicroTx docs, 2024-11-27)
- microservices.io describes Try as: "An 'initiator' of the transaction asks other microservices (participants) to reserve resources or place them in escrow… analogous to putting items in a shopping cart." (microservices.io, search snippet — direct page access blocked)
Phase 2a — Confirm (Commit)
- If all participants successfully reserved resources in Try, the coordinator instructs all participants to confirm.
- Confirm executes the real business logic using the already-reserved resources. For example: frozen funds are moved to the escrow/destination account; reserved stock is marked as sold. (Apache Seata [PRE-2024])
- "Confirm is the second-stage commit, executing the real business logic." (Apache Seata [PRE-2024])
- Oracle MicroTx maps Confirm to an HTTP PUT on the reservation URI. (Oracle MicroTx docs, 2024-11-27)
- Asynchronous Confirm optimisation: after a successful Try phase, the global transaction can be considered complete from the business perspective. A background task executes Confirm asynchronously — improving perceived user-facing latency. (Apache Seata v1.5.1 blog [PRE-2024])
- Alipay example: Confirm phase moves pre-frozen funds to intermediary escrow account and can run asynchronously in off-peak hours without changing the user-visible outcome. (Apache Seata [PRE-2024])
Phase 2b — Cancel (Rollback)
- If any participant fails Try, times out, or the initiator decides to abort, the coordinator instructs all participants that successfully reserved to cancel.
- Cancel releases reserved resources back to the available state. For example: "frozen" funds return to available; reserved stock quantity is restored. (Apache Seata [PRE-2024]; ddhigh.com [PRE-2024])
- Oracle MicroTx maps Cancel to an HTTP DELETE on the reservation URI. (Oracle MicroTx docs, 2024-11-27)
- Oracle whitepaper [PRE-2024] notes: "each participant provides a timeout value indicating how long it will hold a reservation. After that period of time, the participant can unilaterally decide to cancel the reservation" — creating the possibility of heuristic outcomes if some participants cancel while others confirm.
TCC vs Two-Phase Commit (2PC)
| Dimension | TCC | 2PC (XA) |
|---|---|---|
| Lock type | Application-level soft lock (reserved state) | Database-level row/table lock |
| Blocking | Non-blocking: multiple concurrent transactions can reserve separate portions of same resource | Blocking: all participants wait for coordinator decision before releasing locks |
| Coordinator failure | Coordinator only tracks outcomes; resource reservation times out automatically | Coordinator SPOF: participants can wait indefinitely if coordinator crashes after PREPARE |
| Backend coupling | Heterogeneous systems (any service implementing Try/Confirm/Cancel API) | XA-compliant databases only |
| Development effort | High: business must implement all three operations on every participant | Low: XA is transparent; developer only demarcates transaction boundaries |
| Consistency claim | Strong isolation on reserved resources; prevents dirty reads during Try phase | ACID isolation |
Oracle [PRE-2024] claims TCC provides "the same global consistency guarantee that the XA transaction model provides." Apache Seata docs and Temporal docs do not make this claim — Seata positions TCC as "high-performance" without asserting XA-level isolation. The Oracle claim rests on the reservation model preventing dirty reads; however, soft locks provide weaker isolation than XA's hard row-level locks. A failed participant during Confirm phase can produce heuristic outcomes requiring manual resolution, which is not possible under XA. Sources: Oracle whitepaper (Copyright 2022, [PRE-2024]); Apache Seata user docs v2.6 (2024); Oracle MicroTx docs (2024-11-27).
Oracle whitepaper source is Copyright 2022 [PRE-2024]. Oracle MicroTx Release 24.2 (2024-11-27) is the current primary source for Oracle's TCC implementation.
TCC vs Saga Pattern
| Dimension | TCC | Saga |
|---|---|---|
| Intermediate state visibility | Reserved resources not visible as committed to concurrent readers during Try phase | Intermediate committed state IS visible to concurrent readers (dirty reads possible between local transactions) |
| Rollback on timeout/error | Automatic: coordinator cancels all reservations on timeout | Manual: requires explicit compensating transaction to be triggered and executed |
| Reservation requirement | Participants must support a reservable resource model | No reservation requirement: any service with a compensating action works |
| Long-running transactions | Not suited: reservations have timeouts; blocking real resources for hours/days is impractical | Well-suited: compensations can trigger days later |
| Western adoption | Limited: dominant in Alibaba/Chinese internet ecosystem | High: Netflix, Uber, and mainstream Western microservices practice |
Atomikos [PRE-2024] argues Sagas "were designed for centralised DBMS, not distributed microservices" and are ill-suited to distributed environments because they "do not cope well with communication failures/timeouts." This directly contradicts mainstream Western microservices practice where Saga (especially choreography) is widely used in production at Netflix, Uber, and other large-scale distributed systems. Temporal, Azure, and AWS all recommend Saga as the primary distributed transaction pattern. Sources: Atomikos blog (2023-02-07 [PRE-2024]); Azure Architecture Center Saga docs (updated 2025-02-25); Temporal Saga Pattern docs (2026).
Three design hazards and their solutions
Every TCC implementation must handle three canonical failure modes (first documented by Ant Financial / Seata team):
1. Empty Rollback
- Problem: Cancel phase arrives before Try phase due to network packet loss. The participant receives a Cancel for a transaction it never processed a Try for.
- Required behaviour: return success and do nothing. Do not reserve any resource.
- Seata v1.5.1 solution (tcc_fence_log): Cancel checks whether a Try record exists in the
tcc_fence_logtable. If no record found, a SUSPENDED record is inserted to block any late-arriving Try, and success is returned. (Apache Seata v1.5.1 blog [PRE-2024])
2. Suspension / Hanging Transaction
- Problem: A slow Try message is delayed in transit. Cancel executes first (correctly, via empty rollback). The late Try then arrives and executes — permanently reserving resources that will never be confirmed or cancelled.
- Required behaviour: refuse the late Try.
- Seata v1.5.1 solution: When a late Try arrives and finds a SUSPENDED status record in
tcc_fence_log, the Try insert fails on primary key conflict. The local transaction rolls back. The resource is never reserved. (Apache Seata v1.5.1 blog [PRE-2024])
3. Idempotency
- Problem: The coordinator may retry Confirm or Cancel due to network failures. Re-executing a Confirm on already-confirmed state (e.g., double-deducting inventory) corrupts data.
- Required behaviour: retried Confirm/Cancel must produce the same result as the first call.
- Seata v1.5.1 solution:
tcc_fence_logrecords per-branch transaction status (tried / committed / rollbacked / suspended). If status is already COMMITTED when Confirm is retried, the method returns success without re-executing. (Apache Seata v1.5.1 blog [PRE-2024])
The Seata tcc_fence_log mechanism is described in a blog post from 2022 [PRE-2024]. The mechanism was introduced in Seata v1.5.1. Current Seata version behaviour should be verified against the latest Apache Seata docs.
The tcc_fence_log mechanism: all writes to this table and business operations execute in the same local database transaction, ensuring atomic success-or-failure of state recording and business action. (Apache Seata v1.5.1 blog [PRE-2024])
Ecommerce use cases
Inventory reservation for flash sales
- TCC allows concurrent reservations without global blocking: two concurrent orders T1 and T2 can both reserve separate portions of the same SKU stock in Try phase without interfering with each other, because each reserves a discrete quantity in an intermediate column. (Apache Seata [PRE-2024])
- This directly addresses the "hot row" problem in high-traffic flash sales where all orders compete for the same inventory row lock. (Apache Seata [PRE-2024])
Order + payment + accounting (core settlement)
- Canonical TCC ecommerce sequence (order + stock): Try phase stores order in EXECUTING state and reserves stock; Confirm phase marks order complete and marks stock as reduced; Cancel phase restores stock and cancels order. (ddhigh.com [PRE-2024])
- Apache Seata positions TCC for "general-purpose" synchronous, deterministic, short-running transactions: order + payment + accounting (financial settlement). (Apache Seata [PRE-2024])
Alipay escrow example
- Try phase deducts buyer's available funds into "pre-frozen" funds (not yet deducted from buyer's balance). (Apache Seata [PRE-2024])
- Confirm phase moves pre-frozen funds to intermediary escrow account. This can run asynchronously in off-peak hours because "pre-frozen" state already signals transaction completion to the user. (Apache Seata [PRE-2024])
Payment authorisation in ecommerce checkout
- Oracle MicroTx: "during the Try phase, the microservice should obtain payment authorisation to ensure the payment can be made" — authorisation is a reservation of payment capacity. (Oracle MicroTx docs, 2024-11-27)
Frameworks and implementations
| Framework | Language | Notes |
|---|---|---|
| Apache Seata | Java | Dominant production framework; originally Fescar/Alibaba; contributed by Ant Financial. Supports AT (non-intrusive), TCC, and Saga modes. TCC is highest-performance but most invasive mode. |
| Hmily | Java | Open-source, ByteDance-adjacent community |
| ByteTCC | Java | Open-source |
| tcc-transaction | Java | Open-source (GitHub) |
| Oracle MicroTx | Language-agnostic (REST/HTTP) | Enterprise implementation; REST-over-HTTP protocol; PUT=Confirm, DELETE=Cancel |
Framework comparison sourced from Apache Seata blog [PRE-2024] (2019). Seata is the dominant production framework per multiple sources searched in 2026, but framework rankings should be verified against current GitHub activity.
Performance characteristics
- TCC is described as "more efficient than other modes" because "the resource locking in TCC mode is not a true lock, but rather a real local transaction submission that reserves resources in an intermediate state without the need for blocking and waiting." (Apache Seata v1.5.1 blog [PRE-2024])
- Seata's Same-Database Mode optimisation reduces RPC calls between transaction coordinator and resource manager by 50% by storing branch transaction state locally rather than registering with the coordinator on each branch. (Apache Seata v1.5.1 blog [PRE-2024])
[!unverified] The "50% RPC reduction" figure is a qualitative/descriptive claim in the Seata blog, not a benchmarked throughput measurement under production load conditions. No published latency or throughput benchmarks comparing TCC, Saga, and 2PC at production ecommerce scale were found in any source searched (as-of 2026-08-29).
Performance claims sourced from Seata blog 2022 [PRE-2024]. Seata has continued development; current performance figures should be validated against Seata v2+ benchmarks if available.
TCC variants
Asynchronous Guaranteed TCC
- Used where the slave service doesn't affect the master decision (e.g., member registration → email notification). Decoupled via reliable messaging. The second phase runs asynchronously. (Apache Seata [PRE-2024])
Compensated TCC
- Only implements Do + Compensate (no reservation/Try phase). Used for external integrations where the third party only exposes execute/cancel APIs (e.g., airline ticket booking). (Apache Seata [PRE-2024])
- Known limitation of Compensated TCC: because phase 1 executes the full business logic (no resource reservation), rollback/compensation can fail and may require manual intervention. (Apache Seata [PRE-2024])
When to use TCC
Atomikos [PRE-2024] argues: "Use TCC for transactions across owning departments so you get the advantages of Sagas without the drawbacks." Oracle whitepaper [PRE-2024]: "TCC offers similar consistency [to XA] and minimal developer effort if the application can use a reservation model in its transactions."
TCC is appropriate when:
- Services can model their domain as reservable resources with a clear intermediate state
- Strong isolation is needed (preventing dirty reads between concurrent transactions)
- High throughput is required (flash sales, concurrent checkout)
- Transactions are short-lived (reservations expire — not suited for day-long workflows)
TCC is not appropriate when:
- External systems only expose book/cancel APIs without a distinct reservation state (use Compensated TCC variant or Saga Pattern)
- The application cannot model resources in a reservable intermediate state (Oracle whitepaper [PRE-2024])
- Long-running workflows spanning hours or days (use Saga Pattern)
- Development capacity is limited: TCC is "the most invasive" mode, requiring all three operations on every participant. (Apache Seata [PRE-2024])
Key terms
| Term | Meaning |
|---|---|
| Try phase | First phase: reserve resources in intermediate state without committing |
| Confirm phase | Second phase (success path): commit the reserved resources into final state |
| Cancel phase | Second phase (rollback path): release reserved resources back to available state |
| Soft lock | Application-level resource hold in an intermediate state — not a database row lock |
| tcc_fence_log | Seata v1.5.1 database table that prevents empty rollback, suspension, and idempotency failures atomically |
| Heuristic outcome | Inconsistency when some TCC participants Confirm and others Cancel due to timeout — requires manual resolution |
| Empty rollback | Cancel received with no prior Try — participant must return success and do nothing |
| Suspension | Late Try arrives after Cancel already executed — participant must refuse the Try |
Next frontier concepts
- Temporal (workflow engine) — Temporal's Saga-based alternative to TCC; does not implement TCC natively
- Semantic Lock — Saga countermeasure using application-level semaphores; equivalent function to TCC's reservation state but within Saga pattern
- Apache Seata — entity page needed; the dominant Java TCC framework
- Hmily — entity page needed; alternative TCC framework
- Scheduler Agent Supervisor — distributed coordination pattern related to TCC coordinator role
- TCC Fence Log — implementation detail of Seata's hazard-prevention mechanism