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.)
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:
- Python
- TypeScript
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()
async transfer(
context: TransactionContext,
state: Bank.State,
request: TransferRequest
): Promise<PartialMessage<TransferResponse>> {
const fromAccount = Account.lookup(request.fromAccountId);
const toAccount = Account.lookup(request.toAccountId);
await fromAccount.withdraw(context, { amount: request.amount });
await toAccount.deposit(context, { amount: request.amount });
return {};
}
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:
- Python
- TypeScript
# Transactions like writers can alter state directly.
state.account_ids.append(account.state_id)
// Transactions like writers can alter state directly.
state.accountIds.push(newAccountId);