Interview question
Save an order and outbox event in one SQLAlchemy transaction
Persists business state and durable publication intent atomically while leaving broker delivery to an idempotent publisher.
TL;DR
Persists business state and durable publication intent atomically while leaving broker delivery to an idempotent publisher.
AsyncSession transaction ownership, flush, stable event identity, versioned payloads, rollback, and duplicate delivery.
Practice the problem like a real interview: restate, reason, implement, and test.
When an order is placed, persist the order and an OrderPlaced outbox row in one database transaction. Do not publish to the broker inside that transaction. The outbox row needs a stable event ID, aggregate ID, event type and version, JSON payload, creation time, and pending state.
Next in Python Backend Practical Labs: pytest PostgreSQL constraint
order insert + outbox insert succeed -> both commit
outbox serialization/insert fails -> neither commits
publisher crashes after broker accepts -> same event ID is retried
import json
from datetime import datetime, timezone
from uuid import uuid4
async def place_order(session, command):
async with session.begin():
order = Order(customer_id=command.customer_id, status="pending")
session.add(order)
await session.flush()
event_id = uuid4()
payload = {
"event_id": str(event_id),
"order_id": order.id,
"customer_id": command.customer_id,
}
session.add(OutboxMessage(
event_id=event_id,
aggregate_id=str(order.id),
event_type="OrderPlaced",
event_version=1,
payload_json=json.dumps(payload, separators=(",", ":")),
created_at=datetime.now(timezone.utc),
status="pending",
))
return order.id
The command performs two bounded inserts. Publisher scans need an index on pending status and ordering fields and remain proportional to claimed batch size.
Spot a weak answer, missing edge case, or clearer explanation? Send it in.
Say thanks with a standalone, one-time $5 contribution. No account required.