Transactions and savepoints
Wrap a unit of work in a transaction so it commits all-or-nothing. Nested transactions become savepoints, so an inner failure can be contained without losing the outer work.
See Transactions for the reference; this is a working walkthrough.
A basic transaction
Call transaction with a block on DB.shared (or on any model). It commits on
normal return and returns the block's value:
1 2 3 4 5 | |
A model exposes the same wrapper:
1 2 3 | |
Rolling back
Throw X::Rollback to abort. It rolls the transaction back and is swallowed (it
does not propagate out of the block):
1 2 3 4 5 6 7 8 | |
Any other exception also rolls the transaction back, but rethrows so the caller sees it.
Nested savepoints with :requires-new
A plain nested transaction joins the outer one. Pass :requires-new to open a
savepoint instead, so the inner block can fail on its own:
1 2 3 4 5 6 7 8 9 10 11 | |
Isolation levels
The outermost transaction can request an isolation level (it is an error on a nested one):
1 2 3 | |
read_uncommitted, read_committed, repeatable_read, and serializable are
accepted.
After-commit / after-rollback callbacks
Register transactional callbacks on a model in BUILD; they fire after the
outer transaction settles, not when the record is written:
1 2 3 4 5 6 | |
There are also after-create-commit, after-update-commit,
after-destroy-commit, and after-save-commit. A record written inside a
savepoint that rolls back fires after-rollback, while the surrounding
committed records still fire after-commit.