Depot.Transaction
depot/lib/transaction.march Depot.Transaction: transactions for Depot.Repo.
Phase 1.1 of the ROADMAP. The contract is deliberately narrow:
- Top-level
run(conn, fn c -> ...)issuesBEGIN, runs the callback,
then `COMMIT` on `Ok(_)` or `ROLLBACK` on `Err(_)`.
* Nested `run` calls (same connection) degrade to `SAVEPOINT sp_<depth>` /
`RELEASE SAVEPOINT` / `ROLLBACK TO SAVEPOINT`, so inner failures can
be caught without tanking the outer transaction.
* `run_pool(pool, ...)` checks out a connection, pins it for the whole
transaction (`Pool.with_conn_pinned`), then delegates to `run`.Depth tracking uses a single Vault table keyed by the connection's stable string key (Db.conn_key). The pool hands out one DbConn per checkout, so the key uniquely identifies the transaction context.
Functions
Run callback inside a transaction on conn.
Returns Ok(v) after COMMIT when the callback returns Ok(v). Returns Err(reason) after ROLLBACK when the callback returns Err(reason). Wire-level errors from BEGIN / COMMIT / ROLLBACK themselves are surfaced verbatim — the caller sees exactly one Err(String).
Nested calls (same connection) use SAVEPOINT sp_<depth> / RELEASE SAVEPOINT / ROLLBACK TO SAVEPOINT so an inner Err only rolls back its own work.
match Depot.Transaction.run(conn, fn c ->
match Db.query(c, "INSERT INTO users ...") do
Ok(_) -> Ok(())
Err(e) -> Err(e)
end
) do
Ok(_) -> ...
Err(e) -> ...
endCheck out a pooled connection, pin it for the transaction's lifetime, and run callback inside a BEGIN / COMMIT block.
Returns the callback's Result directly (unwrapped from the pool layer so success and failure paths collapse to a single Result).