Bank transfers without distributed transactions

Let there be multiple physically distributed databases where each database contains ("owns") a set of bank accounts. A bank account is owned by exactly one participating database.

It is possible to achieve high performance, strongly consistent monetary transfers between accounts with the following properties:

This can be achieved by having each participating database contain:

  1. a persistent queue of deposit records for each of its peers. A deposit record represent a promise to transfer money to an account on the peer.
  2. a sequence number for the number of deposit records it has processed from each peer persistent queue.

The persistent queues are regarded as holding money (just like bank accounts) for the purposes of double entry bookkeeping.

A local transaction on one of the participating databases can atomically do any combination of the following as long as it conforms to double entry book-keeping (a transaction never gains or loses money overall):

It is easy to impose the constraint that no accounts are overdrawn (have negative balances) because we only have deposit records (a promise to send money), never a promise to receive money.

Example

The following example shows how $10 is transferred between two banks without needing distributed transactions.

Initial state

Let bank B1 own account A1 and bank B2 own account A2. Initially both accounts have a balance of $100.

Bank B1 has a persistent queue Q2 which holds deposit records to be sent to bank B2. Q2 is initially empty.

Bank B2 has a persistent sequence number NQ2 which records the number of deposit records in Q2 it has processed.

Local atomic transaction on bank B1

In a local atomic transaction on the database of bank B1, $10 is removed from A1 and converted into a deposit record which is appended to Q2.

Local atomic transaction on bank B2

In a local atomic transaction on the database of bank B2, the deposit record is marked as processed by incrementing NQ2 and $10 is added to A2.