From f6ded9af7527ce323d162121cc75682ca19781b6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Jul 2026 06:11:39 +0000 Subject: [PATCH] Document how Datasette manages transactions Adds an internals documentation section describing the task-equals- transaction model for write connections, the autocommit read path, and the cross-project constraint that Datasette and sqlite-utils both rely on the legacy sqlite3 transaction handling - Python 3.12+ autocommit= style connections are not supported and any migration would need to be coordinated across both projects. Refs #2831 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01N76afGMhBRQk528VF1LTpR --- docs/internals.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/internals.rst b/docs/internals.rst index 9a5f3f50..1f1873e6 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -2180,6 +2180,17 @@ Functions run using ``execute_isolated_fn()`` share the same queue as ``execute_ The return value of the function will be returned by this method. Any exceptions raised by the function will be raised out of the ``await`` line as well. +.. _internals_database_transactions: + +How Datasette manages transactions +---------------------------------- + +Each mutable database has a single write connection, owned by a dedicated write thread that executes queued write tasks one at a time. Each task submitted with ``transaction=True`` (the default) runs inside its own transaction: Datasette executes ``BEGIN IMMEDIATE`` before invoking the task, commits if it completes and rolls back if it raises. One write task equals one transaction, and writes made by a task only become visible to readers when the task completes. + +Read connections never open transactions - each read statement executes in autocommit mode with its own implicit SQLite read snapshot. + +Datasette's write connections rely on the legacy transaction handling of Python's ``sqlite3`` module (connections opened with ``isolation_level=`` rather than the ``autocommit=`` parameter introduced in Python 3.12). This is a deliberate constraint shared with `sqlite-utils `__, which refuses connections created with ``autocommit=True`` or ``autocommit=False`` - any future migration to the modern transaction API would need to be coordinated across both projects. Plugins should not change the transaction control mode of connections Datasette passes to them. + .. _database_close: db.close()