What is a Transaction?
A transaction is a logical unit of work that either completes entirely or fails completely. It follows the ACID properties to ensure data reliability in database systems.
ACID Properties
- Atomicity
- Ensures that all operations within a transaction are completed; otherwise, none are.
- Example: If inventory is reduced but the payment fails, the inventory update must be rolled back.
- Consistency
- Guarantees that a transaction will bring the system from one valid state to another.
- Example: Inventory should never go negative, even if there are concurrent orders.
- Isolation
- Ensures that concurrently executing transactions do not affect each other.
- Example: Two users placing an order simultaneously should not see inconsistent data.
- Durability
- Once a transaction commits, the changes are permanent—even in the case of system failure.
- Example: Payment confirmation must persist even if the service restarts.
Monolithic vs. Microservices Transactions
Monolithic Architecture
- All business logic resides in a single application using a single database.
- Transaction management is straightforward using
@Transactional. - Example: Order placement, inventory deduction, and payment processing happen within one transaction boundary.
Microservices Architecture
- Each service (Order, Inventory, Payment) has its own database.
- ACID compliance becomes difficult due to distributed data management.
- Requires distributed transaction management mechanisms.
Distributed Transaction Management
In a microservices setup, a transaction might span across multiple independent services.
There are two broad categories:
1. Synchronous Transaction Management
- Two-Phase Commit (2PC)
- Three-Phase Commit (3PC)
2. Asynchronous Transaction Management
- Saga Pattern (covered separately)
Two-Phase Commit (2PC)
Overview
2PC ensures atomic commitment across multiple microservices by coordinating in two phases:
Phase 1: Prepare Phase
- A service (e.g., Order Service) acts as the coordinator.
- It sends a “prepare” message to all participants (e.g., Inventory, Payment).
- Each participant:
- Checks if it can complete its operation.
- Locks necessary resources.
- Replies with “Yes” or “No” to the coordinator.
Phase 2: Commit Phase
- If all participants vote Yes:
- Coordinator sends “commit” messages.
- Participants apply changes and send acknowledgment.
- If any participant votes No:
- Coordinator sends “rollback” messages.
- All participants revert to the original state.
Example
A customer places an order:
- Order Service sends prepare to Inventory and Payment services.
- If both services confirm (inventory exists and payment details are valid), the coordinator sends a commit.
- If one fails, rollback is triggered for all.
Three-Phase Commit (3PC)
Overview
3PC enhances 2PC by introducing an additional phase to reduce blocking and uncertainty due to failures.
Phases
- Can Commit Phase
- Coordinator asks if participants are ready to commit.
- Participants respond with “Yes” or “No”.
- Pre-Commit Phase
- If all vote “Yes”, coordinator sends a “pre-commit” message.
- Participants lock resources and prepare to commit.
- Participants acknowledge they are ready.
- Do Commit Phase
- Coordinator sends “do commit” message.
- Participants commit changes and respond with success.
Advantages Over 2PC
- Avoids blocking: Participants do not remain indefinitely in uncertain states.
- Safer recovery: If a coordinator crashes, participants can decide based on their state.
- Reduced inconsistency: The added pre-commit step gives participants time to prepare safely.
Example Comparison
Imagine an online order with Order, Inventory, and Payment services:
- 2PC: Inventory locks stock after “Yes” reply; if coordinator crashes before commit, it remains blocked.
- 3PC: Inventory receives pre-commit before locking. If coordinator crashes, inventory can release the lock safely due to timeout and pre-commit awareness.
Drawbacks of 2PC
- Coordination Overhead
- Multiple communication rounds.
- Increased latency and complexity.
- Single Point of Failure
- Coordinator crash can leave participants in uncertain states.
- Blocking Nature
- Participants wait until a final decision is made.
- Reduces system responsiveness.
- Inconsistent State Risk
- If coordinator crashes after partial commit, some services may commit, others may not.
- Network Dependency
- Delays or dropped packets can cause timeouts and unwanted rollbacks.
- Timeout Challenges
- Timeout too short: unnecessary rollbacks.
- Timeout too long: poor user experience.
When to Use 2PC or 3PC
- Use 2PC when strong consistency is required, and failure rates are low (e.g., banking transactions).
- Use 3PC when the system needs better fault tolerance and reduced locking, especially in unreliable networks.
Summary Table: Monolithic vs. Microservices Transactions
| Feature | Monolithic | Microservices |
|---|---|---|
| DB Architecture | Single Database | Distributed Databases |
| ACID Handling | Easy with @Transactional | Complex, needs coordination |
| Failure Handling | Simple rollback | Requires coordination/compensation |
| Example | E-commerce in single app | E-commerce split across services |