Understanding Local vs Distributed Transactions: ACID, Pitfalls, and Solutions
This article explains the fundamentals of local transactions, highlights their advantages and limitations, introduces the challenges of distributed transactions across services and databases, and reviews common solutions such as 2PC, reliable messaging, TCC, and max‑effort notification.
Local Transaction
Before discussing distributed transactions, we first examine local transactions, which are managed by a resource manager (e.g., a DBMS) on a single node.
Local Transaction Process
A diagram (omitted) shows that the resource manager handles the transaction locally.
Advantages of Local Transactions
Support strict ACID properties.
High reliability and efficiency because operations are confined to the local resource.
All transaction work can be performed within the resource manager.
Simple programming model.
Disadvantages of Local Transactions
Lack of capability to handle distributed transaction scenarios.
Isolation granularity is determined by the resource manager, not by developers (e.g., a single database record).
ACID Properties
Atomicity : All operations in a transaction either complete fully or not at all.
Consistency : Database constraints remain intact before and after the transaction.
Isolation : Concurrent transactions do not interfere with each other; intermediate states are invisible.
Durability : Once committed, changes are persisted and survive failures.
Distributed Transaction
As applications evolve from monolithic to micro‑service architectures, a single business operation often spans multiple services and databases, creating the need for distributed transactions.
Typical Scenario Diagram
(Diagram omitted) shows a monolithic system split into independent micro‑services, each with its own database.
Example code demonstrates a method annotated with @Transactional that updates order, account, points, and accounting records. Adding the annotation alone does not solve distributed transaction problems when the data resides in different databases.
Scenarios That Trigger Distributed Transactions
Cross‑JVM Process
Micro‑services communicate via REST or RPC; for example, an order service calls an inventory service to deduct stock. Since the services run in separate JVMs, a distributed transaction is required.
Cross‑Database Instance
When a single operation touches multiple database instances (e.g., order database and transaction database), each instance uses its own connection, leading to a distributed transaction.
Multiple Services Sharing One Database
Even if several services access the same physical database, they do so through separate sessions, which also creates distributed transaction challenges.
Note: Both cross‑instance and multi‑service‑single‑DB scenarios share the root cause of multiple database sessions.
Distributed Transaction Solutions
2PC (Two‑Phase Commit)
The transaction is split into a Prepare phase and a Commit phase. In the Prepare phase, the transaction manager asks each participant to write undo/redo logs but not commit. In the Commit phase, participants either commit or roll back based on the manager’s decision. Locks must be released in the final phase.
Reliable Message + Final Consistency
After a local transaction succeeds, the initiator sends a message to a message broker. Consumers receive the message and complete their part of the transaction, ensuring eventual consistency. The approach requires handling atomicity between local transaction and message send, guaranteeing reliable delivery, and implementing idempotency to avoid duplicate consumption.
TCC (Try‑Confirm‑Cancel)
The process consists of three stages:
Try : Perform business checks and reserve resources (isolated operation).
Confirm : After all Try phases succeed, commit the reserved resources.
Cancel : If any Try fails, roll back the reserved resources.
When using TCC, developers must address empty rollbacks, idempotency, and hanging transactions.
Maximum Effort Notification
This pattern aims for eventual data consistency across heterogeneous systems by repeatedly notifying target systems. Implementations must ensure idempotent processing and provide mechanisms for data reconciliation.
@Transactional(rollbackFor = Exception.class)
public void submitOrder() {
orderDao.update(); // update order
accountService.update(); // modify account balance
pointService.update(); // adjust points
accountingService.insert(); // insert transaction record
merchantNotifyService.notify(); // notify payment result
}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.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
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.
