Mastering Distributed Transactions: From 2PC to Seata AT Mode

This article explains the fundamentals of single‑ and multi‑data‑source transactions, surveys common distributed transaction models such as 2PC, 3PC, TCC, status‑table and message‑middleware approaches, and then details the implementation of Seata's AT mode with diagrams, code snippets, and lock handling.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Mastering Distributed Transactions: From 2PC to Seata AT Mode

0. Introduction

From CPU to memory, disk, operating system, and network, computer systems contain many unreliable factors. Engineers use various software and hardware techniques—TCP for reliable transmission, RAID for storage, ARIES‑based transaction mechanisms for databases—to ensure correct processing. This article first introduces the ACID properties of single‑node database transactions, then points out the challenges of operating multiple data sources in distributed scenarios, and finally presents common distributed transaction solutions that can provide ACID guarantees across multiple data sources, ending with an in‑depth look at the Seata AT mode implementation.

1. Single‑Data‑Source Transaction & Multi‑Data‑Source Transaction

A single‑data‑source transaction relies on the database's built‑in transaction mechanism to guarantee atomicity, consistency, isolation, and durability (ACID). For example, MySQL InnoDB uses Undo Log, Redo Log, and the ARIES algorithm. In a microservice architecture, each service maintains its own database, such as a shopping service that calls inventory and order services. The shopping service must operate on two databases (inventory and order) to complete a purchase, but local transaction mechanisms cannot ensure global ACID across these databases, prompting the need for distributed transaction mechanisms.

2. Common Distributed Transaction Solutions

2.1 Distributed Transaction Model

Key terms: transaction participant (e.g., each database), transaction coordinator (e.g., shopping‑service), Resource Manager (RM) and Transaction Manager (TM). TM manages multiple RMs, coordinating local transactions to achieve global ACID.

2.2 Two‑General Problem and Idempotency

The classic two‑general problem illustrates network unreliability: a messenger may be captured, leaving the commander uncertain whether the opponent will attack. Similarly, HTTP requests or MySQL inserts may succeed on the server but the client receives no response, requiring the client to retry until an acknowledgment is received. To avoid duplicate effects, operations must be idempotent.

2.3 Two‑Phase Commit (2PC) & Three‑Phase Commit (3PC)

2PC consists of a prepare phase where the coordinator asks participants to ready their local transactions, and a commit phase where, if all participants responded yes, the coordinator instructs them to commit; otherwise it rolls back. Participants must implement Prepare(), Commit(), and Rollback() interfaces, often via the XA protocol. 2PC suffers from performance bottlenecks, lock retention, and coordinator failure risks. 3PC adds an extra inquiry phase and timeout mechanisms to reduce blocking, but still cannot fully handle coordinator crashes.

2.4 TCC Solution

TCC (Try‑Confirm‑Cancel) splits a global transaction into two phases: a try phase that locks resources and returns yes if successful, and a confirm phase that commits if all tries succeeded, otherwise a cancel phase rolls back. Idempotency is ensured by retrying confirm/cancel until all participants acknowledge success.

2.5 Transaction Status Table Solution

Distributed Transaction ID | Transaction Content | Transaction Status
---|---|---
global_trx_id_1 | Call repo‑service to deduct inventory; call order‑service to create order | 1: Initial
 | 2: Inventory deducted
 | 3: Order created

The coordinator updates the status table after each successful service call. A background task scans the table; if a transaction does not reach the final state within a threshold, it retries the failed steps. Persistent failures are marked as error for manual intervention.

2.6 Message‑Middleware Based Final‑Consistency Solution

This approach uses a message queue (e.g., RabbitMQ) to achieve eventual consistency. The order‑service inserts an order record and a local message record in the same transaction, then a background worker sends the message to the queue. The inventory‑service consumes the message, deducts stock, and acknowledges the queue. Retries handle network “two‑general” failures, and a deduplication table prevents duplicate processing.

start global_trx
call inventory service to deduct stock
call order service to create order
commit global_trx

Both producer and consumer place the send/consume operations inside local transactions to guarantee atomicity. Retry logic and a deduplication table ensure that messages are neither lost nor processed multiple times, achieving final consistency across microservices.

3. Seata in AT Mode Implementation

3.1 AT Mode Workflow Overview

Seata AT mode builds on relational database local transactions, intercepting SQL to record custom undo logs. The two phases are: (1) acquire local lock, execute local transaction, record undo log, and release lock; (2) if global commit is needed, asynchronously delete undo logs; if rollback is needed, replay undo logs to compensate.

3.2 AT Mode Detailed Workflow

In the e‑commerce example, the shopping‑service calls the inventory‑service to deduct stock and the order‑service to create an order within a single global transaction. Sample tables for inventory (t_repo) and orders (t_order) are shown below.

t_repo:
id | production_code | name   | count | price
10002 | 20002 | yy 鼠标 | 199 | 100.0
t_order:
id | order_code   | user_id | production_code | count | price
30003 | 2020102500002 | 40002 | 20002 | 1 | 100.0

The AT first‑phase flow diagram shows that local transactions commit and release locks before the global decision, unlike XA where locks are held until the second phase. Seata stores undo logs in an undo_log table containing branch_id, xid, beforeImage, afterImage, etc.

undo_log table structure:
id | branch_id | xid | context | rollback_info | log_status | log_created | log_modified
… | … | … | … | beforeImage & afterImage | … | … | …

If all branches commit successfully, Seata sends a global commit; each branch simply deletes its undo logs. If any branch fails, Seata triggers a global rollback, and each branch replays its undo logs to compensate. The article also explains how global locks guarantee write isolation and how read isolation can be achieved using SelectForUpdateExecutor to block reads until the global lock is released.

4. Conclusion

All the discussed models—2PC, 3PC, TCC, status‑table, message‑middleware, and Seata AT—aim to achieve the four ACID properties for distributed transactions. While they share the core idea of a coordinator managing participant progress, practical implementations often deviate from the strict XA standard to meet performance and scalability requirements in high‑concurrency environments.

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.

2PCtccDistributed TransactionsSeataAT Mode
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.