Skip to main content

Transactions

Transactions ensure that a group of database operations either all succeed or all fail together.

Basic Usageโ€‹

import ryx

async with ryx.transaction():
order = await Order.objects.create(total=99.99, user_id=1)
await OrderItem.objects.create(order_id=order.pk, sku="ABC123")
# Commits automatically on clean exit
# Rolls back automatically on exception

With Explicit Handleโ€‹

Access the transaction handle for savepoint management:

async with ryx.transaction() as tx:
order = await Order.objects.create(total=50.00, user_id=1)

await tx.savepoint("before_items")
try:
for item in cart_items:
await OrderItem.objects.create(order_id=order.pk, **item)
except ValidationError:
await tx.rollback_to("before_items")
raise

Nested Transactionsโ€‹

Nested transaction() calls create savepoints automatically:

async with ryx.transaction():
await do_something()

async with ryx.transaction(): # Creates a SAVEPOINT
await do_something_else()
# If this raises, only the inner savepoint rolls back

Check Active Transactionโ€‹

tx = ryx.get_active_transaction()
if tx:
print("Inside a transaction")

How It Worksโ€‹

Ryx uses contextvars.ContextVar to propagate the active transaction through async call stacks. This means you don't need to pass the transaction object around โ€” it's automatically available to all database operations within the context.

Next Stepsโ€‹

โ†’ Validation โ€” Field and model validation