macro_rules! transaction {
($db:expr, |$tx:ident| $body:block) => { ... };
}Expand description
Runs a block in a transaction: committed when it evaluates to Ok,
cancelled when it evaluates to Err (? leaves the block, not the
function). When the transaction conflicts with a concurrent one, the
block runs again in a new transaction, up to
TRANSACTION_ATTEMPTS times.
ⓘ
let user = slave_framework::transaction!(&db, |tx| {
let user: Option<User> = tx.query("CREATE ...").await?.take(0)?;
tx.query("CREATE ...").await?.check()?;
Ok(user)
})?;The error type must implement MaybeConflict.
To make two transactions that read the same rows and write different ones
conflict (e.g. “keep at least one owner”), have both write one shared
record, such as the parent row.
A macro rather than a function taking an async closure: the futures of
async closures are not provably Send, which MCP tools require.