A SQLite transaction groups changes so a failure can roll back the group rather than leaving a partially inserted batch.
Python sqlite3 transactions: bind values and roll back failed batches
Operation contract
The fixture creates an in-memory receipt table with a positive-amount check. Two bound inserts run in one transaction: the second violates the check, so the first is rolled back too. A later valid insert commits and the final query returns that one row. SQL values use placeholders rather than string formatting.
Failure and ownership boundary
The connection context controls commit/rollback, not connection closure; the fixture closes it in finally. Its in-memory database also disappears after closure. Target-database isolation, concurrent writers, durable files and migration recovery require their own tests. Python inventory project: validate a batch before replacing stored state and Java JDBC transactions: atomic updates and rollback address related failure rules.
Working program
import sqlite3
connection = sqlite3.connect(":memory:")
try:
connection.execute("CREATE TABLE receipt (id INTEGER PRIMARY KEY, amount INTEGER CHECK(amount > 0))")
try:
with connection:
connection.execute("INSERT INTO receipt VALUES (?, ?)", (41, 125))
connection.execute("INSERT INTO receipt VALUES (?, ?)", (42, -1))
except sqlite3.IntegrityError:
print("batch rolled back")
print(connection.execute("SELECT count(*) FROM receipt").fetchone()[0])
with connection:
connection.execute("INSERT INTO receipt VALUES (?, ?)", (43, 75))
print(connection.execute("SELECT id, amount FROM receipt ORDER BY id").fetchall())
finally:
connection.close()Output
batch rolled back
0
[(43, 75)]Costs and limits
The test inserts three tiny candidate rows and queries a count and one result. Database plan, disk durability, locking schedules and pooled connection behavior are outside this in-memory fixture.
Common Mistakes
- Bind values instead of building SQL with f-strings.
- The connection transaction context does not close the connection.
Connected lessons
Python string formatting: format text without building SQL syntax, Python context managers: clean up on success and failure, Java JDBC transactions: atomic updates and rollback.
Apply this boundary
Python SQLite project: transactional batches, duplicate IDs and reopen checks.
Related Python operation checks
Django atomic transactions: rollback the batch and defer callbacks, Python SQLite job project: reject conflicting replays by request identity.
Follow the related contract
Flask SQLite application: own the request connection and verify a clean reopen.
Check the next state boundary
Python SQLite writer contention: reject a busy transaction before changing state, Python SQLite outbox project: commit a receipt and its pending event together, Python database interview: a retained SQLite read snapshot can be older than a committed write.
Follow the ownership and update boundary
Python SQLite savepoints: discard one substep without committing the batch.
Trace the next boundary
Python SQLite foreign keys: enable enforcement on each connection, Python SQLite backup project: copy a committed snapshot to another connection.
Follow the integrity boundary
Python SQLite UNIQUE with NULL: an absent key can repeat, Python SQLite upsert: make a replay update explicit.
