Problem
There is no transaction API — only TODO comments. get_or_create even documents "not atomic; wrap in a transaction", but there is nothing to wrap it in. A production ORM needs explicit transactions.
Scope
async with db.transaction(): context manager on BaseDatabase, implemented for Postgres (asyncpg) and MySQL (aiomysql) — BEGIN / COMMIT / ROLLBACK, nested via savepoints (or documented no-nesting for v1).
- Surface at a usable level (e.g.
async with Model.transaction(): or registry-level) so multiple save()/bulk ops share one transaction/connection.
- Make
get_or_create atomic when run inside a transaction; document concurrency guarantees.
- Tests (both backends): commit persists; exception rolls back; rollback leaves DB unchanged; get_or_create race-safety under a transaction.
Design
Capture the connection-vs-pool / per-task-connection model in an ADR — this constrains future work.
Problem
There is no transaction API — only TODO comments.
get_or_createeven documents "not atomic; wrap in a transaction", but there is nothing to wrap it in. A production ORM needs explicit transactions.Scope
async with db.transaction():context manager onBaseDatabase, implemented for Postgres (asyncpg) and MySQL (aiomysql) — BEGIN / COMMIT / ROLLBACK, nested via savepoints (or documented no-nesting for v1).async with Model.transaction():or registry-level) so multiplesave()/bulk ops share one transaction/connection.get_or_createatomic when run inside a transaction; document concurrency guarantees.Design
Capture the connection-vs-pool / per-task-connection model in an ADR — this constrains future work.