Sequence of Events for a Distributed Transaction

Here is a step-by-step description of events that occur before and during the transaction commit sequence.

Before a transaction is committed, the following events occur:
  1. When a transaction is started the transaction coordinator creates a globally unique ID (TXID) and creates a work space (TXState) to track operations. If the transaction is started from a thin client connection, the coordination happens on the server to which the client is connected. Note that transactions are started implicitly in JDBC: the end of one transaction implicitly starts a new one.

  2. All updates in the scope of a transaction are immediately propagated to all replicas in parallel and are partially coordinated on each data store (cohort). Each member that owns the data involved in the transaction manages the state in a local TXState. When updates are received by a cohort, it attempts to obtain local write locks on the rows. A cohort fails immediately if the rows are already locked by another transaction. Failure to obtain locks results in the coordinator implicitly rolling back the entire transaction and releasing all the locks on the data hosts.

  3. SQLFire only detects Write-Write conflicts. To prevent rows fetched in the transaction from being modified before transaction commit, SQLFire supports select for update where the selected rows are locked before the result set can be returned.

  4. While the transaction is in progress the updates are maintained only in the TXState on the data stores, completely isolated from other concurrent connections.

  5. Any constraint checks on the rows are immediately applied, and failures result in a constraint violation exception.
    Note: In this release of SQLFire, constraint violations also implicitly roll back the transaction.
  6. Readers do not normally acquire any locks unless the rows being read are about to be committed. Transactional read operations are applied to the TXState first, before they are applied to the committed state.

  7. When using the REPEATABLE_READ isolation level, all rows from selects are written first to the TXSTate before they are returned to the application.

These events occur during the transaction commit sequence:
  1. When a commit message is received by the coordinator, it dispatches a single commit message to all of the cohorts. Because the rows are already locked and constraints applied during the transaction, it is certain that the transaction will not fail due to conflicts.

  2. Each cohort guarantees transaction atomicity by making sure that no concurrent transaction can see partially-committed state on the data store. Note that even though SQLFire guarantees that no concurrent access sees the partially-committed state of a transaction on any single cohort, the commit phase does not guarantee that to be the case across all of the cohorts that are involved in the transaction.

  3. Each cohort applies the TXState changes to the tables in memory, and releases all the locks before acknowledging to the coordinator.

Note: Because the outcome of the transaction is assured at commit time, the coordinator does not wait for individual commit replies from the cohorts before returning the committed transaction to the initiating thread. If the same connection immediately initiates another operation on the same data, then the cohorts wait for pending replies from the previous transaction (as described in Step 3) before applying the change.