What is a Transaction?
A transaction is a group of one or more operations treats as a single unit of work.
Either:
- All operations succeed: transaction is committed
- Any operation fails: everything is rolled back
Example:
Bank transfer:
- Deduct 1000 from Account A
- Add 1000 to Account B
If step 2 fails, step 1 must be undone.
Transaction States (Lifecycle)
A transaction doesn't just go from start -> success/failure. It passes through multiple well-defined states:
1 Active
The transaction has started and is executing operations (reads/writes).
Example:
Updating account balances, inserting rows, etc.
This is the “in progress” state.
2 Partially Committed
The transaction has executed all its operations successfully
But the changes are not yet permanently saved to disk
Think: “Everything looks good, but not finalized yet”
3 Committed
The transaction is successfully completed
All changes are permanently stored (durable)
After this point, changes cannot be undone.
4 Failed
Something went wrong during execution
Could be due to:
- System crash
- Constraint violation
- Deadlock
The transaction cannot proceed further.
5 Aborted (Rolled Back)
The system undoes all changes made by the transaction
Database is restored to the previous consistent state
After abort:
- It may be restarted or completely discarded.
State Transition Flow
Here's how a transaction typically moves:
Active → Partially Committed → Committed
↓
Failed → AbortedOr more explicitly:
- Start -> Active
- If all operations succeed -> Partially Committed
- If everything is safely written -> Committed
If something fails:
- Active -> Failed -> Aborted
ACID Properties (Core of Transactions)
Transactions are defined by the ACID principles.:
A – Atomicity
- “All or nothing”
- No partial updates
C – Consistency
- Database remains in a valid state
- Rules (constraints, invariants) are preserved
I – Isolation
- Concurrent transactions don't interfere
- Each transaction behaves as if it's alone
D – Durability
- Once committed, data is permanently stored
- Survives crashes
Types of Transaction Systems
Single-node (Traditional DB)
Distributed Transactions
When data spans multiple services/databases.
A distributed transaction is a set of operations on data that is performed across two or more databases. It is typically coordinated across separate nodes connected by a network, but may also span multiple databases on a single server.
Why Do we Need Distributed Transactions?
Unlike an ACID transaction on a single database, a distributed transaction involves altering data on multiple databases. Consequently, distributed transaction processing is more complicated, because the database must coordinate the committing or rollback of the changes in a transaction as a self-contained unit.
In other words, all the nodes must commit, or all must abort and the entire transaction rolls back. This is why we need distributed transactions.
Problem:
What if one service succeeds and another fails?
For example:
Service A updates Database A
Service B updates Database B
What if:
- A succeeds
- B fails
Now the system is inconsistent.
Two-Phase Commit (2PC)
In it we have Coordinator (Transaction Manager)
- Controls the transaction
- Decides commit or rollback
Participants (Cohorts)
- Individual services/databases
- Execute the transaction steps
The Two Phases:
Phase 1: Prepare Phase (Voting Phase)
Coordinator asks:
“Can you commit?”
Steps:
- Coordinator sends PREPARE requests to all participants
- Each participant:
- Execute the transaction locally
- Writes changes to a log (but does NOT commit yet)
- Replies:
- Yes (ready to commit)
- No (cannot commit)
Phase 2: Commit Phase
Case 1: All vote YES
- Coordinator sends COMMIT
- All participants finalize changes
Case 2: Any vote NO
- Coordinator sends ROLLBACK
- All participants undo changes
Flow Diagram:
Coordinator
|
+---------+---------+
| | |
P1 P2 P3
Phase 1:
Coordinator → PREPARE → All
P1 → YES
P2 → YES
P3 → YES
Phase 2:
Coordinator → COMMIT → AllFailure case:
P2 → NO
Coordinator → ROLLBACK → AllGuarantees:
Atomicity across systems:
- Either all commit or all rollback
Consistency:
- No partial updates
Problems with 2PC
- Blocking Problem
- If coordinator crashes after “prepare”:
- Participants are stuck waiting
- They cannot decide commit/rollback themselves
- If coordinator crashes after “prepare”:
- Single Point of Failure
- Coordinator failure can halt the system
- Slow Performance
- Requires multiple network round trips
- Participants must lock resources until final decision
- Not Scalable
- Doesn't work well in large microservices architectures
Where 2PC Is Used
- Traditional distributed databases
- Banking systems (where consistency is critical)
- Some enterprise systems
Three-Phase Commit (3PC)
Three-Phase Commit (3PC) is an extension of Two-Phase Commit (2PC) designed to solve its biggest flaw: blocking when the coordinator fails.
It adds an extra step so that participants are never left in an uncertain (blocked) state.
Why 3PC Was Introduces
Recall the main issue with 2PC:
If the coordinator crashes after “prepare”
-> Participants are stuck waiting forever (blocked)
3PC fixes this by:
- Adding a middle phase
- Ensuring no participants is left unsure whether to commit or abort
Phase 1: Can Commit (Voting Phase)
Coordinator asks:
“Can you commit?”
- Participants check if they execute the transaction
- Respond:
- YES
- NO
- Same as 2PC prepare phase (but lighter)
Phase 2: PreCommit (Ready-to-Commit Phase)
If all say YES:
- Coordinator sends: PRE-COMMIT
- Participants:
- Execute transaction
- Write to logs
- Enter a “prepared” state
- Acknowledge back
Now everyone is ready and know others are ready too
Phase 3: DoCommit (Final Phase)
- Coordinator sends: COMMIT
- Participants finalize the transaction
Failure Handling (Key Advantage_
This is where 3PC shines
Case: Coordinator crashes
- In 2PC: participants are stuck
- In 3PC: participants can decide themselves
Why?
Because of the PreCommit phase:
- If a participant is in:
- Before PreCommit -> safe to abort
- After PreCommit -> safe to commit
No ambiguity -> no blocking
SAGA
The Saga pattern is a way to manage distributed transactions in modern systems (especially microservices) without using heavy protocols like 2PC or 3PC.
Instead of locking everything and committing all at once, SAGA breaks a transaction into a sequence of smaller, independent steps, each with a compensating action if something goes wrong.
A Saga = a series of local transactions + rollback steps (compensations)
Each service:
- Execute its own transaction
- Publishes an event or calls the next service
- If something fails -> undo previous steps using compensating actions.
Simple Example (E-commerce Order)
Normal Flow:
- Order Service -> Create order
- Inventory Service -> Reserve item
- Payment Service -> Charge user
Failure Case:
If payment fails:
- Undo inventory reservation
- Cancel order
Instead of “rollback” like DB transaction, Saga uses business-level undo.
Two Types of Saga:
1 Choregraphy-Based Saga (Event-Driven)
- No central controller
- Each service listens and reacts to events
Flow:
- Order created -> emits event
- Inventory listens -> reserves stock -> emits event
- Payment listens -> processes payment
If failure:
- Services emit compensation events
Pros:
- Fully decentralized
- Scales well
Cons:
- Hard to debug
- Complex event chains
2 Orcestration-Based Saga
- A central orchestrator control the flow.
Flow:
- Orchestrator -> Order service
- Orchestrator -> Inventory service
- Orchestrator -> Payment service
If failure:
- Orchestrator triggers rollback steps
Pros:
- Easier to manage and debug
- Clear flow
Cons:
- Central dependency (like a mini coordinator)
Leave a comment
Your email address will not be published. Required fields are marked *
