Transactions#
The SQLSpec plugin supports two transaction modes: autocommit and manual commit. Choose the mode that fits your application's error handling and rollback requirements.
Commit Modes#
- Autocommit (default)
Each statement commits automatically. Use this for read-heavy workloads or when you don't need atomic multi-statement operations.
- Manual Commit
You control when to commit or rollback. Use this for write operations that must succeed or fail together.
commit modes#from sqlspec import SQLSpec
from sqlspec.adapters.sqlite import SqliteConfig
from sqlspec.extensions.litestar import CommitMode, SQLSpecPlugin
sqlspec = SQLSpec()
sqlspec.add_config(
SqliteConfig(
connection_config={"database": ":memory:"},
extension_config={"litestar": {"commit_mode": CommitMode.autocommit}},
)
)
sqlspec.add_config(
SqliteConfig(
connection_config={"database": ":memory:"},
extension_config={"litestar": {"commit_mode": CommitMode.manual}},
),
name="manual",
)
plugin = SQLSpecPlugin(sqlspec=sqlspec)
Rollback on Error#
In manual mode, uncaught exceptions trigger an automatic rollback before the response is sent. This keeps your database consistent when handlers fail.
@post("/transfer")
async def transfer(db: AsyncSession, data: TransferRequest) -> dict:
await db.execute(
"UPDATE accounts SET balance = balance - :amount WHERE id = :from_id",
amount=data.amount,
from_id=data.from_account,
)
await db.execute(
"UPDATE accounts SET balance = balance + :amount WHERE id = :to_id",
amount=data.amount,
to_id=data.to_account,
)
await db.commit() # Both updates succeed or both rollback
return {"status": "transferred"}
Nested Transactions#
Use savepoints for nested transaction scopes. SQLSpec translates begin_nested()
to savepoints on databases that support them.