
Durgesh Tiwari
Author
In a distributed system, data is usually stored across multiple services or databases instead of a single database. When a user performs one action, different services may need to work together to complete that request.
For example, when a customer books a flight, different services handle different tasks. One service reserves the seat, another processes the payment, and another generates the ticket. All these services must complete their work correctly.
This is where Distributed Transactions become important.
A Distributed Transaction makes sure that all related operations either finish successfully or none of them are saved. This helps keep the data correct and consistent across all services.
In simple words, a Distributed Transaction makes sure that multiple services complete one task together. If one operation fails, the entire transaction is cancelled.
Distributed Transactions are an important topic in System Design because modern applications use microservices and distributed databases to serve millions of users every day.
Managing a transaction inside a single database is easier because one database controls the entire process.
In a distributed system, multiple services and databases work independently. They communicate over a network, and each service has its own database. Because of this, keeping every service synchronized becomes much more difficult.
For example, imagine a travel booking application.
The booking service successfully reserves a hotel room, but the payment service fails because of a network issue.
Now the system has a reserved room without a successful payment. This creates inconsistent data and may cause problems for both the customer and the business.
Distributed transactions become difficult because:
Multiple services are involved – One user request may require several independent services.
Network failures can happen – A service may not receive or send a response because of network problems.
Services respond at different speeds – Some services finish quickly, while others take more time.
One service may fail unexpectedly – A single failure can interrupt the entire transaction.
Keeping data consistent is harder – Every service must end with the correct and matching data.
Because of these challenges, distributed systems use special techniques to coordinate different services and complete transactions safely.
Atomicity means a transaction is treated as one complete unit of work.
If every operation succeeds, the transaction is completed. If even one operation fails, all completed changes are cancelled or rolled back.
This prevents incomplete data from being stored in the system.
In simple words, Atomicity means either everything succeeds or nothing is saved.
Atomicity follows a simple process:
A transaction starts.
Each service performs its assigned task.
If every operation is successful, the transaction is completed.
If any operation fails, all completed changes are rolled back.
The system returns to its previous state.
This makes sure that the transaction is either fully completed or completely cancelled.
Suppose a customer transfers ₹5,000 from Bank Account A to Bank Account B.
The transaction includes these steps:
Deduct ₹5,000 from Account A.
Add ₹5,000 to Account B.
Now imagine the money is deducted from Account A, but the system fails before adding it to Account B.
In this situation, the transaction should be cancelled, and the deducted amount should be returned to Account A.
This ensures that money is not lost and both bank accounts remain correct.

Atomicity helps distributed systems process transactions safely and correctly.
Prevents Partial Transactions – The system never saves incomplete work.
Protects Data Accuracy – All related operations finish together or fail together.
Reduces Data Errors – Failed transactions do not leave incorrect records.
Improves Application Reliability – Users receive correct results even when failures occur.
Builds User Trust – Customers can safely perform important actions such as payments and money transfers.
Two-Phase Commit (2PC) is a protocol used in Distributed Transactions to make sure that all participating services or databases make the same decision.
If every service agrees, the transaction is completed. If even one service cannot complete the transaction, all services cancel their changes.
In simple words, Two-Phase Commit makes sure that every service either saves the transaction together or cancels it together.
The Two-Phase Commit Protocol works in two simple phases.
In this phase, the Transaction Coordinator asks every participating service whether it is ready to complete the transaction.
Each service checks whether it can perform its task successfully and sends one of these responses:
Yes – The service is ready to commit the transaction.
No – The service cannot complete the transaction.
If even one service replies No, the coordinator immediately cancels the transaction.
If every participating service replies Yes, the coordinator sends a Commit request.
Each service then saves its changes permanently.
If any service rejected the request during the Prepare Phase, the coordinator sends a Rollback request, and every service cancels its changes.
Coordinator
│
Prepare Request
│
┌───────────┼───────────┐
▼ ▼ ▼
Service A Service B Service C
│ │ │
Yes Yes Yes
└───────────┼───────────┘
│
Commit Request
│
┌───────────┼───────────┐
▼ ▼ ▼
Commit Commit CommitSuppose a customer books a flight through an online travel application.
The transaction involves three services:
The Booking Service reserves the flight seat.
The Payment Service charges the customer's card.
The Ticket Service generates the flight ticket.
First, the coordinator asks all three services if they are ready.
If all three services reply Yes, the booking is completed successfully.
If the Payment Service replies No because the payment fails, the coordinator tells every service to cancel its work. The seat reservation is removed, and no ticket is generated.
This ensures that the customer never receives a half-completed booking.
Two-Phase Commit is useful when an application needs strong data consistency.
Maintains Atomicity – All services complete the transaction together.
Prevents Partial Updates – The system avoids incomplete transactions.
Keeps Data Consistent – Every participating service has the same transaction result.
Suitable for Critical Applications – Commonly used in banking, finance, and payment systems.
Although 2PC provides strong consistency, it also has some limitations.
Slower Performance – Every service must wait before the transaction finishes.
Coordinator Dependency – If the coordinator fails, the transaction may become blocked.
Higher Network Communication – Multiple messages are exchanged between services.
Limited Scalability – It becomes less efficient as the number of services increases.

The Saga Pattern is a popular way to manage Distributed Transactions in a microservices architecture. It allows multiple services to complete a business operation without locking all services at the same time.
Instead of treating the entire process as one large transaction, the Saga Pattern breaks it into a series of small local transactions. Each service completes its own work independently.
If one step fails, the system does not roll back the entire transaction automatically. Instead, it uses compensating transactions to undo the changes made by the previous services.
In simple words, the Saga Pattern completes a task step by step. If one step fails, it reverses the completed steps to keep the system consistent.
The Saga Pattern follows these steps:
The Order Service creates a new order.
The Payment Service processes the payment.
The Inventory Service updates the product stock.
The Shipping Service prepares the delivery.
If every step is successful, the transaction is completed.
However, if any service fails, the Saga starts compensating transactions to undo the completed work.
For example:
Refund the customer's payment.
Cancel the order.
This helps the application return to a consistent state without locking every service.
Order Created
│
▼
Payment Success
│
▼
Inventory Failed
│
▼
Refund Payment
│
▼
Cancel OrderSuppose a customer books a vacation through an online travel website.
The booking process includes these steps:
The Flight Service books the flight ticket.
The Payment Service charges the customer's card.
The Hotel Service books the hotel room.
Now imagine the Hotel Service cannot book the room because no rooms are available.
Instead of keeping the flight booking and payment, the Saga Pattern starts compensating transactions.
The payment is refunded.
The flight booking is cancelled.
As a result, the customer is not charged for an incomplete booking, and all services remain consistent.

The Saga Pattern is widely used in modern microservices-based applications because it improves scalability.
Supports High Scalability – Each service works independently.
No Long-Running Locks – Services do not wait for each other to finish.
Improves Performance – Local transactions are completed quickly.
Ideal for Microservices – Fits well with distributed applications.
Handles Failures Gracefully – Compensating transactions help recover from errors.
Although the Saga Pattern is powerful, it also has some challenges.
More Complex to Build – Every service needs compensation logic.
Temporary Data Inconsistency – Different services may not be updated at the same time.
Extra Development Effort – Compensating transactions must be carefully designed and tested.
Two-Phase Commit (2PC) | Saga Pattern |
|---|---|
Uses one global transaction for all services. | Uses multiple local transactions across different services. |
Provides strong consistency because every service finishes together. | Provides eventual consistency by correcting failures with compensating transactions. |
All services commit or roll back at the same time. | Completed steps are reversed if a later step fails. |
Slower because every service must wait for the coordinator. | Faster because services complete their work independently. |
Can become blocked if the transaction coordinator fails. | Does not depend on one blocking coordinator. |
Best suited for traditional distributed database systems. | Best suited for microservices and cloud-based applications. |
Easier to understand but harder to scale for large systems. | More complex to implement but easier to scale for modern applications. |

The right approach depends on your application's needs. Some systems need strong data consistency, while others focus on high scalability and better performance.
Choose Two-Phase Commit (2PC) when every service must complete the transaction together, and partial updates are not acceptable.
Strong consistency is required – All services must have the same data.
Partial transactions are not allowed – Either the whole transaction succeeds or it fails completely.
Only a few services are involved – 2PC works better with a limited number of services.
Data accuracy is more important than speed – Correct data is the highest priority.
Examples:
Banking systems
Financial transactions
Payment processing
Accounting systems
Choose the Saga Pattern when building microservices that need to handle many users and high traffic.
The application uses microservices – Each service can manage its own local transaction.
High scalability is required – Services can work independently without waiting for each other.
Temporary inconsistency is acceptable – The system can become consistent after compensating transactions finish.
Business processes take longer to complete – Suitable for workflows involving multiple services.
Examples:
E-commerce platforms
Travel booking systems
Food delivery applications
Order management systems
Different applications use different transaction approaches based on their business needs.
For example, an e-commerce platform usually uses the Saga Pattern because it runs on multiple microservices and needs to handle a large number of users. If one service fails, compensating transactions undo the completed steps.
A banking system, on the other hand, usually uses Two-Phase Commit (2PC) because money transfers require strong consistency. Every database must either complete the transaction successfully or roll back all changes.
Choosing the right approach helps applications stay reliable, scalable, and consistent.
Distributed Transactions help multiple services or databases complete a single business operation while keeping the data consistent. Since different services communicate over a network, failures can happen at any time, making distributed transactions more difficult than transactions in a single database.
Distributed Transactions ensure that all related services maintain consistent and accurate data.
Atomicity ensures that a transaction either completes fully or is completely rolled back.
Two-Phase Commit (2PC) uses a coordinator to make sure all participating services commit or roll back the transaction together.
Saga Pattern breaks a large transaction into smaller local transactions and uses compensating transactions to recover from failures.
2PC is a good choice for applications that require strong consistency, such as banking and financial systems.
Saga Pattern is better for microservices and cloud applications that need high scalability and better performance.
Choosing the right transaction approach helps you build distributed systems that are reliable, scalable, and able to handle failures without losing data.