Mastering Seata TCC: Theory, Types, and Practical Implementation

This article explains the TCC (Try‑Confirm‑Cancel) transaction model, its three practical variants, and provides a step‑by‑step guide with code examples for integrating Seata TCC into a Spring‑Boot e‑commerce order service, while addressing common pitfalls such as idempotency, empty rollbacks, and hanging transactions.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Mastering Seata TCC: Theory, Types, and Practical Implementation

What is the TCC model?

TCC (Try‑Confirm‑Cancel) is a two‑phase commit pattern for distributed transactions. Each business operation must provide a Try method that validates the request and reserves the required resources (often by locking), a Confirm method that commits the actual business logic and releases the locks, and a Cancel method that rolls back the reservation when the Try fails.

Two‑Phase Process

Try : perform business checks, reserve resources, and optionally lock them.

Confirm : execute the real business operation and release the reserved resources.

Cancel : release the reserved resources when the Try does not succeed.

Illustrative E‑Commerce Example

The example uses an order‑creation flow with two services: inventory and order. Initial stock is 100. A purchase of 2 triggers the Try phase, which freezes 2 units of inventory and creates an order with status PENDING. If Try succeeds, the Confirm phase finalizes the order and releases the lock; otherwise the Cancel phase restores the inventory and deletes the pending order.

Three Practical TCC Variants

General‑Purpose TCC : All participant services directly join the global transaction. Suitable for short‑lived, tightly coupled operations such as core e‑commerce services.

Asynchronous Assurance TCC : Participants communicate via a reliable message service. The Try step only persists the message; Confirm sends it, Cancel removes it. This reduces coupling but adds message‑service overhead and fits low‑sensitivity, passive workflows.

Compensating TCC : Participants expose Do and Compensate methods instead of full three‑method TCC. It reduces participant changes but requires careful handling of compensation failures.

Seata Support for TCC

Seata provides AT, TCC, SAGA, and XA transaction modes. The following sections focus on implementing TCC with Seata.

Demo Scenario

Client calls the order API.

Inventory service reserves stock (Try).

Order service creates a pending order (Try).

Transaction coordinator decides to Confirm or Cancel based on Try outcome.

TCC Interface Definition

@LocalTCC
public interface OrderTccService {
    @TwoPhaseBusinessAction(name = "orderTcc", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean tryCreateOrder(BusinessActionContext ctx, Long productId, Long num);
    boolean confirm(BusinessActionContext ctx);
    boolean cancel(BusinessActionContext ctx);
}

Try Method

The Try method checks for a previous Cancel (to avoid hanging), freezes inventory, creates a pending order, and records an idempotency key.

@Transactional
public boolean tryCreateOrder(BusinessActionContext ctx, Long productId, Long num) {
    // 1. Prevent hanging by checking transaction log
    // 2. Freeze inventory
    frozenStorage();
    // 3. Create pending order
    saveOrder();
    // 4. Record idempotency key (class + xid)
    IdempotentUtil.add(key, System.currentTimeMillis());
    return true;
}

Confirm Method

Confirm ensures idempotency, retrieves Try parameters from the context, releases the frozen stock, updates the order status, and clears the idempotency entry.

@Transactional
public boolean confirm(BusinessActionContext ctx) {
    // 1. Idempotency check
    if (IdempotentUtil.get(key) == null) return true;
    // 2. Get parameters from context
    Long productId = ctx.getActionContext("productId");
    // 3. Release frozen stock
    cleanFrozen();
    // 4. Update order status to COMPLETED
    updateOrder();
    // 5. Remove idempotency entry
    IdempotentUtil.remove(key);
    return true;
}

Cancel Method

Cancel logs the cancel state (to prevent hanging), checks idempotency, restores inventory, deletes the pending order, and cleans the idempotency data.

@Transactional
public boolean cancel(BusinessActionContext ctx) {
    // 1. Record cancel state in transaction log
    transactionLog.insert(xid, "cancel");
    // 2. Idempotency & empty‑rollback guard
    if (IdempotentUtil.get(key) == null) return true;
    // 3. Restore inventory
    rollbackFrozen();
    // 4. Delete pending order
    delOrder();
    // 5. Clean idempotency entry
    IdempotentUtil.remove(key);
    return true;
}

Handling Common TCC Exceptions

Empty Rollback : Cancel may be invoked without a successful Try. Guard by checking the idempotency entry before executing Cancel.

Idempotency : Confirm/Cancel can be retried. Use a transaction‑status table or in‑memory map (e.g., IdempotentUtil) to ensure each phase runs only once.

Hanging (Cancel before Try) : Network delays can cause Cancel to arrive first. Record Cancel in a log table and have Try verify that no Cancel record exists before proceeding.

Transaction Log Table Example

CREATE TABLE `transactional_record` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `xid` VARCHAR(100) NOT NULL,
  `status` INT COMMENT '1=try 2=commit 3=cancel',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

The Cancel method inserts a row with status=3. The Try method queries this table; if a Cancel record is found, it aborts to avoid hanging.

Configuration Highlights

Define a Seata transaction group (e.g., tx-service-group) in Nacos and ensure all services share the same SEATA_GROUP value.

Enable local transactions with @Transactional on each TCC method.

Use @LocalTCC on the service interface to activate TCC support.

Conclusion

The TCC model provides a flexible way to achieve distributed consistency with shorter lock durations compared to AT mode. By defining a TCC interface, implementing Try/Confirm/Cancel with proper idempotency checks, and using a transaction‑status table to guard against empty rollbacks and hanging, developers can reliably integrate Seata TCC into microservice architectures.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javamicroservicesSpring BootTCCdistributed transactionsSeata
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.