Transactions¶
Every repository method (get_items, create_item, etc.) wraps its operation in a transaction via self.transaction(). self.transaction() reuses an existing session from the context if one exists, otherwise creates a new one.
Explicit transaction¶
You can open an explicit transaction when you need to group several operations:
async with repository.transaction():
product1 = await repository.create_item(ProductTable(name="Laptop", price=999.99))
product2 = await repository.create_item(ProductTable(name="Mouse", price=29.99))
If any operation raises an exception, the entire transaction is rolled back.
Reusing an existing session¶
Nested transaction() calls yield the same session — no new savepoint is created:
async with repository.transaction(), repository.transaction():
items = [item async for item in repository.get_items()]
Nested transactions (savepoints)¶
nested_transaction() creates a SQLAlchemy savepoint. When no outer session exists it starts a new session with a savepoint. On exception the savepoint is rolled back, leaving any outer transaction unaffected:
try:
async with repository.nested_transaction():
await repository.create_item(ProductTable(name="Keyboard", price=79.99))
raise ValueError("Rollback nested")
except ValueError:
pass
# Keyboard was rolled back; previous items remain
This is useful for partial rollback inside a larger transaction. See Multi-Repo Transactions for container-level savepoints.