March Docs

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 -> ...) issues BEGIN, 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

fnrunrun(tx_conn, tx_cb)#

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) -> ...
  end
fnrun_poolrun_pool(rp_pool, rp_cb)#

Check 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).