Notes on Two-phase Commit

I recently came across a good description of two-phase commit from actordb’s document. I decide to borrow it as a note. The following is copied from actordb’s document:

3.2.3 Multi-actor transactions
Multi-actor transactions need to be ACID compliant. They are executed by a transaction manager. The manager is itself an actor. It has name and a transaction number that is incremented for every transaction.

Sequence of events from the transaction manager point of view:

  1. Start transaction by writing the number and state (uncommitted) to transaction table of transaction manager actor.
  2. Go through all actors in the transaction and execute their belonging SQL to check if it can execute, but do not commit it. If actor successfully executes SQL it will lock itself (queue all reads and writes).
  3. All actors returned success. Change state in transaction table for transaction to committed.
  4. Inform all actors that they should commit.

Sequence of events from an actors point of view:

  1. Actor receives SQL with a transaction ID, transaction number and which node transaction manager belongs to.
  2. Store the actual SQL statement with transaction info to a transaction table (not execute it).
  3. Once it is stored, the SQL will be executed but not committed. If there was no error, return success.
  4. Actor waits for confirm or abort from transaction manager. It will also periodically check back with the transaction manager in case the node where it was running from went down and confirmation message is lost.
  5. Once it has a confirmation or abort message it executes it and unlocks itself.

Problem scenarios:

  1. Node where transaction manager lives goes down before committing transaction: Actors will be checking back to see what state a transaction is in. If transaction manager actor resumes on another node and sees an uncommitted transaction, it will mark it as aborted. Actors will in turn abort the transaction as well.
  2. Node where transaction manager lives goes down after committing transaction to local state, but before informing actors that transaction was confirmed. Actors checking back will detect a confirmed transaction and commit it.
  3. Node where one or more actors live goes down after confirming that they can execute transaction. The actual SQL statements are stored in their databases. The next time actors start up, they will notice that transaction. Check back with the transaction manager and either commit or abort it.