This is concerned with getting all nodes to agree on the outcome of a transaction.
2PC
The application reads and writes data on multiple database nodes which are participants. When the application is ready to commit, the coordinator sends a prepare request to each node asking them if they are ready to commit. If all participants reply yes, then a commit request is sent. Otherwise, an abort request is sent. A participant can only reply yes if all transaction data can be written to disk under all circumstances.
Warning
This is all well and good until a coordinator crashes. Then, the coordinator needs to read its transaction log and the commit point of 2PC comes down to single-node atomic commit on the coordinator. Therefore this is also not really stateless.
3PC
Note that a network with bounded delay and nodes with bounded response times is assumed here to guarantee Atomicity. This also required a perfect way to identify failure.
XA Transactions
Implements 2PC across heterogeneous technologies. This is a C API for interfacing with the transaction coordinator. Make sure your driver supports this API. The coordinator still needs to restart and read its transaction log to decide what to commit or abort, it just uses the XA callback to do so.