How to Solve Distributed Transactions in Microservices: From 2PC to TCC and Reliable Messaging
This article analyzes the challenges of distributed transactions in microservice architectures, explains ACID, CAP and BASE theories, compares consistency models, and evaluates practical solutions such as two‑phase commit, local message tables, TCC, and reliable messaging with code examples and implementation details.
Microservice Development and Transaction Challenges
Microservice architecture splits a monolithic application into many loosely coupled services, improving scalability and agility but introducing complex inter‑process communication and distributed transaction problems.
ACID Principles
Atomicity : All steps succeed or none do.
Consistency : Database constraints must remain valid after a transaction.
Isolation : Concurrent transactions do not interfere with each other.
Durability : Once committed, a transaction persists permanently.
Consistency Theory: CAP and BASE
The CAP theorem states that a distributed system can simultaneously guarantee at most two of Consistency, Availability, and Partition tolerance. Many systems choose AP (e.g., Cassandra) or CP (e.g., HBase). BASE (Basically Available, Soft state, Eventual consistency) relaxes strict consistency to achieve higher scalability.
Consistency Models
Strong consistency – all replicas see the same data immediately.
Weak consistency – no guarantee of immediate visibility.
Eventual consistency – replicas converge over time.
Local Transaction
A transaction that runs within a single database and a single process, without involving multiple data sources.
Typical Distributed Transaction Solutions
Two‑Phase Commit (2PC)
Local message table (eventual consistency)
TCC (Try‑Confirm‑Cancel) compensation model
Two‑Phase Commit (2PC)
Based on the XA protocol, 2PC consists of a voting phase where participants report readiness, followed by a commit/rollback phase coordinated by a transaction manager. Drawbacks include a single‑point‑of‑failure for the coordinator, synchronous blocking, and possible data inconsistency if some participants fail to receive the final decision.
Local Message Table (Eventual Consistency)
Inspired by eBay’s approach, business operations write a message to a local table within the same database transaction, then asynchronously forward the message to a message queue (e.g., Kafka). The consumer processes the message and performs its own business logic, retrying on failure. This pattern guarantees eventual consistency while avoiding distributed locks.
DROP TABLE IF EXISTS `rp_transaction_message`;
CREATE TABLE `rp_transaction_message` (
`id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'Primary key',
`version` INT(11) NOT NULL DEFAULT '0' COMMENT 'Version',
`editor` VARCHAR(100) DEFAULT NULL COMMENT 'Editor',
`creater` VARCHAR(100) DEFAULT NULL COMMENT 'Creator',
`edit_time` datetime DEFAULT NULL COMMENT 'Edit time',
`create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Create time',
`message_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'Message ID',
`message_body` LONGTEXT NOT NULL COMMENT 'Message content',
`message_data_type` VARCHAR(50) DEFAULT NULL COMMENT 'Data type',
`consumer_queue` VARCHAR(100) NOT NULL DEFAULT '' COMMENT 'Consumer queue',
`message_send_times` SMALLINT(6) NOT NULL DEFAULT '0' COMMENT 'Retry count',
`areadly_dead` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'Dead flag',
`status` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'Status',
PRIMARY KEY (`id`),
KEY `AK_Key_2` (`message_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;The accompanying Java service interface defines methods for saving, confirming, sending, retrying, and deleting messages, as well as pagination support.
Message Handling Logic
Classes such as MessageBiz and AccountingMessageListener illustrate how waiting‑confirm and sending‑timeout messages are processed, how retry intervals are configured, and how dead messages are marked.
Comparison with Conventional MQ ACK
Traditional MQ workflows (produce → persist → ACK → consume → ACK) cannot guarantee message‑send consistency because the producer’s business operation and the message dispatch may succeed or fail independently.
Message‑Send Consistency Issues
Three naive patterns are shown with pseudocode: (1) DB operation then send MQ, (2) send MQ then DB operation, (3) wrap both in a Spring @Transactional. All suffer from scenarios where the DB rolls back but the message remains sent, leading to inconsistency.
TCC Compensation Model
TCC splits a business action into Try (resource reservation), Confirm (final commit), and Cancel (rollback). It offers simpler implementation than 2PC but provides weaker consistency guarantees and requires extensive compensation code.
Reliable Message – Final Consistency (Common Practice)
Many Chinese internet companies adopt reliable‑message patterns, often using RocketMQ’s transactional messages or custom implementations. The typical flow is:
A system sends a “prepared” message to MQ.
If the prepared message succeeds, A executes its local transaction.
On local success, A sends a confirm message; on failure, it sends a rollback message.
B receives the confirm and executes its own transaction.
MQ periodically checks prepared messages and triggers callbacks to resolve uncertain states.
If B’s transaction fails, it retries until success or escalates to manual compensation.
Maximum Effort Notification
This pattern sends a message to downstream services, retries a configurable number of times on failure, and finally gives up, suitable for scenarios with low transactional strictness.
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.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.
