8.9 Software transactional memory
static balances: Map<AccountId, TVar<Money>> = …
atomic {
let a = balances[from].get()
check(a >= amt) // otherwise the transaction waits for a change and retries
balances[from].set(a - amt)
balances[to].update(.add(amt))
}atomic { … }executes the body as a serialisable transaction overTVars. On a conflict the body is restarted.- The body MUST be
pure(exceptTVaroperations); calls with effects are a compile error. check(cond)blocks the transaction until the readTVars change, ifcondis false.atomic(db) { … }is different: a database transaction (§11.2).- A nested
atomic(including through a called function) joins the outer transaction. The body ofatomicis an expression: its value is the result of the run that committed. A panic or cancellation insideatomicdiscards the writes of the transaction and propagates; a task waiting incheckis a cancellation point (§8.6). TVaroutsideatomic. An operation on aTVaroutside anatomicblock is a separate one-operation transaction:getandsetare atomic, but the compoundupdateandswapoutside a block are not atomic as "read-modify-write"; for an atomic update they MUST be executed insideatomic { … }.checkoutsideatomicis a panic. The Standard does not require anorElseoperation (D-8052; DIV-009; D-7521..D-7524).
Related diagnostics
See also
Source: docs/spec/oxl-standard.en.md