Hay dos formas de anidar transacciones en SQLAlchemy. Una es las transacciones virtuales, donde SQLAlchemy realiza un seguimiento de cuántos inicios ha emitido y emite la confirmación solo cuando la transacción más externa se compromete. Sin embargo, la reversión se emite de inmediato. Como la transacción es virtual, es decir, la base de datos no sabe nada sobre el anidamiento, no puede hacer nada con esa sesión después de la reversión hasta que también restituya todas las transacciones externas. Para permitir el uso de transacciones virtuales, agregue el argumento subtransactions=True
a la llamada begin()
. Esta característica existe para permitirle usar control de transacciones dentro de funciones que pueden llamarse entre sí sin hacer un seguimiento si está dentro de una transacción o no. Para que tenga sentido, configure la sesión con autocommit=True
y siempre emita un session.begin(subtransactions=True)
en una función transaccional.
La otra forma de anidar transacciones es usar transacciones anidadas reales. Se implementan usando savepoints. Si restituye una transacción anidada, todos los cambios realizados dentro de esa transacción se retrotraen, pero la transacción externa permanece utilizable y los cambios realizados por la transacción externa continúan allí. Para usar el problema de transacción anidada session.begin(nested=True)
o simplemente session.begin_nested()
. Las transacciones anidadas no son compatibles con todas las bases de datos. función de configuración de la biblioteca conjunto de pruebas de SQLAlchemy sqlalchemy.test.requires.savepoints
dice esto acerca de la ayuda:
emits_warning_on('mssql', 'Savepoint support in mssql is experimental and may lead to data loss.'),
no_support('access', 'not supported by database'),
no_support('sqlite', 'not supported by database'),
no_support('sybase', 'FIXME: guessing, needs confirmation'),
exclude('mysql', '<', (5, 0, 3), 'not supported by database')
En transacciones anidadas PostgreSQL SQLAlchemy funcionar bien.
Las transacciones anidadas (por ejemplo, AUTONOMOUS_TRANSACTION de Oracle) califican como un antipatrón aparte de dos casos: Auditoría (para que el intento sea auditado incluso si la declaración retrocede) y Registro de errores (para capturar dónde/cuándo existen fallas). Todos los demás casos deben usar savepoints. Diablos, el alcance de la transacción no pertenece a ninguna función o procedimiento; debe ser la responsabilidad final del que llama para comprometerse o deshacerse. –
Eso es transcepción. – user