I read some information about 2 Phase Commit/ XA distributed transactions and how JTA does support it. Seems to be that there is many resource managers - RM (eg. RDBMS or JMS), and one TransactionManager (TM) instance that manages global transactions across many RM's.
I know that it's better to use Saga pattern, but it's still interesting to think:
UPD: In JTA world TransactionManager
doesn't provide REST API for managing transactions across microservices. LIXA provides this ability. Article with examples in addition to answers :)
Across microservices, transaction needs to be done by exposing Prepare & Commit APIs. Also there needs to be a transaction manager to coordinate transaction.
For example, Assume there are 2 different Bank and $100 from Account_A of Bank1 has to be transferred to Account_B of Bank2. Furthermore assume that central banking authority is responsible for transaction to finish the way 2PC will work is like following:
Central banking authority(Transaction Manager) will receive request to transfer $100 from Account_A from Bank1 to Account_B from Bank2.
a. https://CentralBank/Transaction?from=Bank1-Account_A&to=Bank2-Account_B&amount=100
Central Bank will save this into its transaction database with some transaction Id = 123. Also it will return transaction id to call, so that at later point it can call to get status of transaction.
a. add transaction 123 in database with status open
PREPARE PHASE Transaction Manager will issue following RPC commands:
a. https://Bank1/Prepare?Account=Account_A&money=100&action=subtract&transactionid=123
b. https://Bank2/Prepare?Account=Account_B&money=100&action=add&transactionid=123
COMMIT PHASE Once it gets successful response for both the calls in Prepare phase, then it moves to Commit phase where it issues following commands:
a. move transaction 123 to committed state
b. https://Bank1/Commit?transactionid=123
c. https://Bank2/Commit?transactionid=123
Once it gets successful response for both the calls in commit phase, central bank can move transaction to Completed state(optional)
If any of the step from PREPARE or COMMIT phase fails then Transaction coordinator aborts the transaction by issuing following commands:
a. move transaction 123 to Failed state
b. https://Bank1/Rollback?transactionid=123
c. https://Bank2/Rollback?transactionid=123
Problem above is form of Distributed Atomic commit, and 2PC is one way of doing it. Also note 2PC has lot of downsides like what if after PREPARE phase central bank crashes. Also what if 4.c step fails but 4.b succeeds, etc. Discussing those is very vast study in itself, but still is something to be aware of. Despite having lot of downsides 2PC is used widely because of its simplicity.
Do we need to use TransactionManager service as a separate microservice to provide 2PC between many microservices?
Theoretically No. If you closely observe any of the bank(Bank1 or Bank2) can act as transaction manager as well(it just needs a separate database table Transaction), but practically lot of time it is kept as separate microservice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With