A repository works inside an open transaction and never holds credentials

Table of Contents

1. Summary

Repositories never open connections and never see credentials. A unit-of-work call takes the tenant, the party and a function. It acquires a connection, begins a transaction with that context (A transaction sets its own tenant context, so any connection serves any tenant), calls the function with the open transaction, commits when the function returns, rolls back when it fails, and releases the connection. Every repository operation takes the transaction as its first argument, so several operations commit together, and a repository has no other way to reach the database.

2. Detail

2.1. The shape

ctx.transact(tenant, party, [&](tx& t) {
    const auto held = ledger.held_by(t, host);
    ledger.requeue(t, held);
});

The context holds the pool, the service account and the acquire policy. It does not hand out connections or credentials; transact is the only way in.

2.2. What runs inside

The generated repositories and the hand-written statements (A hand-written statement is declared once, typed both ways and prepared once) take the same tx. A transaction is read-write unless it is declared read-only, and a read-only transaction tells the store so.

2.3. What comes out

transact returns the function's value or an error with a class (A store error says whether a retry can succeed). A retryable error leaves the decision to retry with the caller, which knows whether the work is safe to repeat.

2.4. What is outside it

The data plane does not use the unit of work. Tick lanes hold connections of the writer role and commit COPY batches (Ticks reach the store through sharded binary COPY in bounded batches), because a tick needs neither the tenant context nor the audit columns.

3. See also

Emacs 29.3 (Org mode 9.6.15)