Watch at EaseHistorias. Respuestas. Perspectiva.

Tecnología · GUÍA PRÁCTICA

Python sqlite3: “cannot start a transaction within a transaction”; encuentra al propietario antes de BEGIN

No es un timeout de bloqueo: la misma conexión ya tiene una transacción activa. Registra el modo de Python y usa una sola transacción externa o SAVEPOINT.

Original diagram mapping Python transaction policy, live connection evidence, and the intended outer transaction owner.
Ilustración original: registra política y estado antes de elegir propietario. Watch at Ease

SQLite rechaza BEGIN dentro de una transacción activa. La primera puede abrirla autocommit=False, isolation_level heredado, un helper exterior o el propio script.

No insertes commit por todas partes. Registra autocommit, isolation_level e in_transaction y nombra al propietario de la unidad de trabajo.

Congela la evidencia del BEGIN fallido

Registra el SQL que falla, autocommit, isolation_level, in_transaction y las operaciones DML, BEGIN, SAVEPOINT, executescript, commit y rollback más recientes de esa conexión.

No deduzcas el propietario por la cercanía en la pila de llamadas: un gestor de contexto exterior o la política de conexión puede haber iniciado ya la transacción.

Elige un solo propietario de la transacción externa

En el modelo controlado por la aplicación, quien llama abre y cierra la unidad de trabajo y los helpers inferiores no ejecutan BEGIN ni COMMIT. En el modelo controlado por el driver se usan la política de conexión y commit/rollback.

Si el script ya incluye BEGIN/COMMIT, no lo envuelvas en otra transacción. Comprueba el rollback provocando un fallo deliberado a mitad de la operación.

Usa SAVEPOINT para un anidamiento intencional

Si el ámbito interior debe poder revertirse por separado, crea un SAVEPOINT con nombre único; usa RELEASE al terminar y ROLLBACK TO seguido de RELEASE cuando falle.

Una biblioteca reutilizable normalmente no debe confirmar una transacción externa que no le pertenece.

Trata BEGIN IMMEDIATE como una decisión sobre el bloqueo

BEGIN IMMEDIATE solo adelanta la adquisición del bloqueo de escritura y tampoco puede ejecutarse dentro de una transacción activa de la misma conexión.

Si un DML en modo heredado ya abrió DEFERRED, decide primero si el trabajo anterior pertenece a la misma unidad antes de conservarla, confirmarla o rediseñar el límite.

Demuestra los límites de commit y rollback

Crea una prueba que falle deliberadamente después de la primera escritura y confirma que se revierte toda la unidad prevista; cubre también la ruta correcta y los helpers anidados.

Comprueba in_transaction en los límites de la API para detectar pronto los cambios de modo o de valores predeterminados.

Original diagram comparing a nested BEGIN failure with one outer transaction and an inner SAVEPOINT.
Ilustración original: el ámbito interno usa SAVEPOINT, no otro BEGIN. Watch at Ease