Skip to main content

Transactions

A transaction method gets exclusive, atomic access to state in order to update it (similar to a writer). But unlike a writer, a transaction can also call the reader, writer, and transaction methods of other states. Those reads and writes all occur as a (distributed) ACID transaction.

A transaction method gets passed a context of type TransactionContext. A TransactionContext can be used to make calls to reader's, writer's, and other transaction methods (although currently nested calls to a transaction method may only read/write mutually exclusive state.)

note

Just like with writer's, to replace an entire state you'll need to do state.CopyFrom(...) in Python and state.copyFrom(...) in Node.js.

Here's an example of a transaction method called Transfer on our Bank state that deposits money in one account and withdraws it from another:

async def Transfer(
self,
context: TransactionContext,
state: Bank.State,
request: TransferRequest,
) -> TransferResponse:
from_account = Account.lookup(request.from_account_id)
to_account = Account.lookup(request.to_account_id)

await from_account.Withdraw(context, amount=request.amount)
await to_account.Deposit(context, amount=request.amount)

return TransferResponse()

Again, like writers, state can be modified directly in a transaction method, for example here is an example from the SignUp method for Bank that stores the account IDs:

# Transactions like writers can alter state directly.
state.account_ids.append(account.state_id)