Explicit Two-Phase Commit (2PC)

An application may opt to use two-phase commit explicitly with BDR. SeeDistributed Transaction Processing: The XA Specification.

The X/Open Distributed Transaction Processing (DTP) model envisages threesoftware components:

  • An application program (AP) that defines transaction boundaries and specifies
    
    • actions that constitute a transaction.

  • Resource managers (RMs, such as databases or file access systems) that provide
    
    • access to shared resources.

  • A separate component called a transaction manager (TM) that assigns identifiers
    
    • to transactions, monitors their progress, and takes responsibility for

    • transaction completion and for failure recovery.

BDR supports explicit external 2PC using the PREPARE TRANSACTION andCOMMIT PREPARED/ROLLBACK PREPARED commands. Externally, a BDR clusterappears to be a single Resource Manager to the Transaction Manager for asingle session.

When bdr.commit_scope is local, the transaction is prepared onlyon the local node. Once committed, changes will be replicated, andBDR then applies post-commit conflict resolution.

Using bdr.commit_scope set to local may seem nonsensical withexplicit two-phase commit, but the option is offered to allow the userto control the trade-off between transaction latency and robustness.

Explicit two-phase commit does not work in combination with either CAMOor the global commit scope. Future releases may enable this combination.

Usage

Two-phase commits with a local commit scope work exactly like standardPostgreSQL. Please use the local commit scope and disable CAMO.

BEGIN;

SET LOCAL bdr.enable_camo = 'off';
SET LOCAL bdr.commit_scope = 'local';

... other commands possible...

To start the first phase of the commit, the client must assign aglobal transaction id, which can be any unique string identifying thetransaction:

PREPARE TRANSACTION 'some-global-id';

After a successful first phase, all nodes have applied the changes andare prepared for committing the transaction. The client must then invokethe second phase from the same node:

COMMIT PREPARED 'some-global-id';