Choosing the Right Distributed Transaction Strategy for Microservices
This article examines the challenges of distributed transactions in microservice architectures and compares five practical solutions—Seata (2PC), TCC, transactional messaging, local message tables, and a custom Kola approach—highlighting their principles, implementations, advantages, and prerequisites.
Demand Origin
In microservice architectures, as services are split, private databases become the norm, leading to distributed transaction problems that are difficult to overcome, with no complete universal solution yet.
Increasing traffic drives database and service sharding, turning many atomic operations into cross‑database or cross‑service transactions. While high performance and scalability often require relaxing consistency, scenarios like billing and e‑commerce still demand strong consistency, prompting the search for mechanisms to guarantee transaction consistency in distributed environments.
Theoretical Foundations
ACID and BASE
References: https://www.infoq.cn/article/2018/08/rocketmq-4.3-release, https://www.txlcn.org/zh-cn/docs/preface.html
2PC
Two‑phase commit (2PC) is the basic distributed transaction scheme.
2PC consists of a prepare phase (voting) where the coordinator asks participants if they can commit, followed by a commit/rollback phase based on all responses, ensuring consistency. It underlies most distributed transaction algorithms.
Requirement Example
Define a recharge scenario: after a successful recharge, the Order service must be marked successful and the user's Account balance increased.
Implementation 1: Seata
Introduction & Framework
Seata (formerly Fescar) is an Alibaba‑open‑source distributed transaction solution that uses a single transaction manager to coordinate services, essentially an implementation of 2PC.
Principle
Seata provides a global transaction manager and proxies SQL queries to manage transactions, acting like middleware.
Recharge Implementation
The solution looks like this:
Both Order and Account services integrate Seata to proxy their transactions.
Code Example
Seata simplifies 2PC; sample code is available in the Seata Samples repository.
Implementation 2: TCC
Introduction
The Try‑Confirm‑Cancel (TCC) model splits a transaction into Try (resource reservation), Confirm (execution), and Cancel (release) phases, as illustrated below.
An activity manager tracks global transaction progress and sub‑transaction states, handling retries and manual intervention to ensure eventual consistency.
Principle
Each sub‑node must implement the TCC interface. Advantages: works with non‑relational services. Disadvantages: added state increases complexity, and many business operations (e.g., bank card recharge) cannot be compensated.
Framework
tx‑lcn (LCN) distributed transaction framework, compatible with Dubbo, Spring Cloud, and Motan, supports various relational databases. Alternatively, Seata MT mode can be used.
Code Example
txlcn-demo
Recharge Implementation
Both Order.done and Account balance updates must implement TCC interfaces, which can be cumbersome; local transactions are preferred when possible.
Implementation 3: Transactional Message
Introduction
In a shopping scenario, a user’s payment and the corresponding loyalty points must be consistent. Traditional approaches can cause mismatches; transactional messaging solves the atomicity between local transaction execution and message sending.
Framework
Apache RocketMQ™ is an open‑source distributed messaging and streaming platform.
Principle
Producer sends a prepare message to MQ.
After the prepare message succeeds, the local transaction is executed.
Based on the local transaction result, a commit or rollback message is returned.
If rollback, MQ discards the prepare message; if commit, MQ delivers it to consumers.
If the producer crashes during the local transaction, MQ repeatedly queries other producers in the same group for status.
Consumer consumption is guaranteed by MQ.
Advantages: friendly to asynchronous operations. Disadvantages: producer must implement a transaction query interface, increasing development complexity.
Code Example
// TODORecharge Implementation
Using MQ ensures that both Order and Account operations either succeed together or fail together; if the Account update fails, the Order must handle the inconsistency.
Implementation 4: Local Message Table
Introduction & Principle
Distributed transaction = local transaction in system A + local transaction in system B + message notification.
System A maintains a log1 table (status: pending). System B maintains log2 (pending) and log3 (completed). Two topics are used: topic1 for A→B notifications, topic2 for B→A acknowledgments.
User obtains a coupon in system A, inserting a record into log1.
A scheduled task polls log1 and sends a message to system B.
System B checks log3 for duplicates, inserts into log2, sends an SMS, then deletes log2 and inserts into log3.
System B notifies system A.
System A deletes the corresponding message.
When network interruptions or crashes occur, retries can be performed via scheduled tasks or MQ, but each operation must be idempotent.
Note: Implement distributed locks for idempotency (see references).
Recharge Implementation
The local message table allows continuation of interrupted transactions.
Implementation 5: Kola’s Solution
Introduction & Principle
Kola’s approach uses a local message table without MQ or relational databases, making implementation more labor‑intensive.
Order table acts as the message table.
Services communicate via HTTP, requiring scheduled retry tasks for failures.
Lack of relational DB makes idempotency harder.
Recharge Implementation
Challenges include high idempotency requirements and complex compensation logic when failures occur.
Improvement suggestions: use MQ for communication and relational databases for local transactions to simplify idempotency.
Summary
We summarize the solutions:
Basic Principle
Implementation
Advantages
Prerequisites
2PC
Seata
Simple
Relational DB
2PC
TCC
Does not rely on relational DB
Implement TCC interface
2PC
Transactional Message
High performance
Implement transaction check interface
Eventual Consistency
Local Message Table
Decentralized
Business intrusion; interfaces must be idempotent
Each scheme has its pros and cons; the choice depends on specific requirements and can be combined flexibly.
For example, with services A (MySQL), B (Redis), and C (Mongo), applying Seata to A and TCC to B/C can achieve consistent distributed transactions.
Thus, combining Seata for relational services and TCC for non‑relational services provides a practical solution.
Reference Articles
RocketMQ 4.3 release – supporting distributed transactions
Seata
txlcn
Distributed Transaction CAP Theory and Solutions
Understanding Distributed Locks
Source: https://kb.cnblogs.com/page/643107/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
