C.W.K.
Stream
Lesson 08 of 10 · published

Transactions — BEGIN, COMMIT, ROLLBACK

~14 min · transactions, acid, writes

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Atomic batches of work

A transaction is a group of statements treated as one atomic unit: either all of them apply or none of them do. SQLite is fully ACID by default — even a single statement runs inside an implicit transaction.

Three explicit shapes:

  • BEGIN; ... COMMIT; — explicit transaction, commit on success.
  • BEGIN; ... ROLLBACK; — abort all changes since BEGIN.
  • SAVEPOINT — nested transaction-like checkpoint inside an outer transaction; RELEASE on success, ROLLBACK TO on failure.

SQLite's transaction modes:

  • DEFERRED (default) — locks acquired only when needed.
  • IMMEDIATE — write lock acquired at BEGIN; other writers block immediately.
  • EXCLUSIVE — exclusive lock; other readers and writers block.
Tip: For 'either I write everything or I write nothing' workflows where you might race another writer, use BEGIN IMMEDIATE. The default DEFERRED can fail at COMMIT time with SQLITE_BUSY if another writer beat you to it — IMMEDIATE fails fast at BEGIN.

Code

Explicit transaction in SQL·sql
BEGIN IMMEDIATE;

INSERT INTO conversations(title) VALUES ('New chat');
INSERT INTO messages(conversation_id, role, content)
VALUES (last_insert_rowid(), 'user', 'Hello');

-- If anything fails before COMMIT, the whole batch can be rolled back:
-- ROLLBACK;

COMMIT;
Python — context manager handles commit/rollback·python
import sqlite3

conn = sqlite3.connect('demo.db')
conn.execute('PRAGMA foreign_keys = ON')

try:
    with conn:                                  # implicit BEGIN/COMMIT
        conv_id = conn.execute(
            'INSERT INTO conversations(title) VALUES (?)',
            ('New chat',)
        ).lastrowid
        conn.execute(
            'INSERT INTO messages(conversation_id, role, content) VALUES (?,?,?)',
            (conv_id, 'user', 'Hello'),
        )
        # An exception here triggers ROLLBACK automatically.
except sqlite3.IntegrityError:
    print('rolled back')

External links

Exercise

Write a Python function that inserts a conversation + a list of messages atomically. Confirm rollback works by deliberately raising in the middle of the loop. Then introduce two concurrent writers and observe the difference between BEGIN DEFERRED and BEGIN IMMEDIATE under contention.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.