Reliable Message-Based Distributed Transaction Consistency Solution
This article explains the fundamentals of distributed transactions, introduces the reliable message eventual consistency approach, analyzes its challenges such as atomicity and message reliability, and presents two practical solutions—local message tables and RocketMQ transactional messages—along with their advantages and drawbacks.
Distributed transactions are frequently asked in technical interviews, and this article introduces a reliable message eventual consistency solution.
What is a Transaction
A transaction strictly adheres to the ACID properties: Atomicity , Consistency , Isolation , and Durability . In simple terms, all operations within a transaction must either all succeed or all fail.
What is a Distributed Transaction
A distributed transaction spans multiple servers, combining several local transactions to ensure that all involved databases maintain data consistency.
Common distributed transaction solutions include 2PC, 3PC, TCC, local message tables, reliable message eventual consistency, and best‑effort notifications.
Reliable Message Eventual Consistency Scheme
This scheme works by having the transaction initiator send a message to a message middleware after its local transaction succeeds; the consumer must receive and process the message, guaranteeing that as long as the message reaches the participant, the overall transaction will eventually become consistent.
Problems with This Approach
The main issues are:
Atomicity between the local transaction and the message (e.g., local commit fails, message not sent; local commit succeeds but message fails, etc.). The fourth scenario can cause inconsistency between the local transaction and the consumer.
Reliability of the consumer receiving the message.
Duplicate consumption of messages, requiring idempotent consumer interfaces.
Solution 1: Local Message Table
A local message table records message logs after a successful local transaction. A scheduled task continuously scans the table and sends pending messages to the middleware.
1) Transaction initiator records a message log after local commit. 2) Scheduled task scans the table. 3) Detected messages are sent to the middleware. 4) Middleware acknowledges successful send to the initiator. 5) Initiator deletes the log. 6) Consumer subscribes and processes the message. 7) Consumer executes its local transaction. 8) Consumer sends an ACK to the middleware.
Key point: the consumer must ensure interface idempotency.
Solution 2: RocketMQ Transactional Message
Since Apache RocketMQ 4.3, transactional messages are supported, effectively encapsulating a local message table inside the MQ to guarantee atomicity between message sending and local transaction execution.
1) Initiator sends a Half transaction message. 2) RocketMQ replies with Half send success. 3) Initiator executes local transaction. 4) If local commit succeeds, initiator sends commit to RocketMQ; otherwise sends rollback . 5) If RocketMQ does not receive confirmation within a timeout, it performs a transaction check. 6) Initiator queries local transaction status. 7) Initiator sends commit/rollback based on the query. 8) After a commit , if RocketMQ does not receive an ACK, it retries.
Advantages : Message data is stored independently, reducing coupling; higher throughput than the local message table approach.
Disadvantages : Each message requires two network requests (half + commit/rollback) and a transaction check interface must be implemented.
Each distributed transaction solution has trade‑offs; selecting the appropriate one depends on the specific business scenario.
End of article.
Wukong Talks Architecture
Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.
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.