Architecture
Consider the same architecture as that of the Event-driven approach. We have an Order Service and a Customer Service with their respective databases. But instead of the Message Broker to communicate the events between the two services, we will talk about the Two-phase commit approach.
Two-phase commit explained
Any transaction made has to go through a transaction manager. This manager ensures that a transaction occurs across all the services (resources). As the name suggests, there are two phases in this mechanism - Commit Request Phase and Commit Phase.
- Commit request phase (also known as voting phase): The manager sends a query to commit message to all the services. The manager then waits for all the services to vote yes or no. Each of the services will perform the transaction up to the point where they would have to commit. The services reply with yes or an agreement if all they are prepared or no if even if one of the services is not prepared.
- Commit phase (also knows as completion phase): There can be two conditions here. Either the manager received yes from all the services or at least one of the services voted no.
- Manager received yes from all services: The manager sends a commit message to all the services asking them to commit the transaction. After the commit, the services send an acknowledgement to the manager after which the transaction is complete.
- Manager received no from one or more of the services: The manager sends a rollback message to all the services asking them to rollback to the state before the actions from the previous phase. After the rollback, the services send an acknowledgement to the manager after which the transaction is undone.
Advantages:
In an environment which has many databases that get affected. It is good to treat them as transactions. Global transactions span on one or more transactional resources, and enlist them all in a single transaction.
Prepare phase can be considered as a dry-run phase to check if the commit is allowed by all the components involved in the system.
Disadvantages:
The transaction manager is a single point of failure. If it fails, then the services will never be able to resolve their transactions.
This protocol is a blocking protocol. The manager will block till it receives the messages from the services which would imply that the locks and resources held by it will not be released till it receives a reply.
If any of the services vetoes the commit, then all the services are asked to perform a rollback on their databases. This ensures consistency among partitions. But being a blocking protocol, this mechanism does not ensure good availability.
CAP Theorem
We know that web services cannot ensure - consistency, availability and partition tolerance. They can, at most, support only two out of the three. ACID, as we know, provides consistency for partitioned databases. If we have to achieve availability instead, we can think of BASE (basically available, soft state, eventually consistent). This basically argues that it is better to have availability along with eventual consistency rather than compromising on availability on the whole. As previously discussed, we can implement an event driven architecture to fulfill this purpose.
Implementations and Examples
- Atomikos: Atomikos TransactionsEssentials is a transaction manager that works without application server, is easier to use and more mature than comparable products.
- Bitronix: The Bitronix Transaction Manager (BTM) is a simple but complete implementation of the JTA 1.1 API. It is a fully working XA transaction manager that provides all services required by the JTA API while trying to keep the code as simple as possible for easier understanding of the XA semantics.
- JTA Standalone Transaction Manager
No comments:
Post a Comment