Saltear al contenido principal

Cuándo y cómo abortar una transacción con XACT_ABORT

La opción XACT_ABORT por defecto está definida en modo OFF en las transacciones que llevamos a cabo.

 

Cuando una transacción levanta un error de run-time, la misma puede llegar a un proceso de rollback en la mayoría de los casos. ¿Solo en la mayoría? ¡Exacto! Eso quiere decir que no siempre sucede esto, lo que quiere decir que una transacción con error que no ha llegado a procesar un rollback, se mantendrá abierta. Esto sucede particularmente cuando un fragmento de todo el código TSQL tiene el error que genera el rollback, pero el resto de la ejecución se mantiene procesando.

 

SUPUESTOS ANTES DE LA DEMO

  • Tenemos una tabla de países y otra de ciudades, donde la segunda hace referencia a la primera a través de una llave foránea. (Creación de tablas con datos acá
  • Contamos con un Procedimiento Almacenado que devuelve todas las ciudades de un determinado país. (Acá todos los scripts
  • Insertamos nuevas ciudades a la tabla en un caso sin respetar la integridad referencial.

Al intentar insertar 6 valores de los cuales 1 no respeta la integridad, ¿qué podemos pensar que va a suceder?

  • ¿Se insertan las filas solo hasta la sentencia que genera error?
  • ¿Se insertan solo las filas que no tienen error?
  • ¿No se inserta nada porque el error es del bloque entero?

En este caso podemos ver en los mensajes de ejecución que evidentemente hay registros que se han insertado y que tambié hay uno que no cumple con la relación de integridad.

xact-abort-sql-server-demo
Error en el uso de la llave foránea

Si ejecutamos el SP que nos muestra todos los registros.

xact-abort-sql-server-demo2
Se insertaron todos los registros menos el que generaba el error (Z4)

¿Es realmente lo que queremos que suceda?

Analicemos bien esta situación.

Ejecutamos un bloque de sentencias INSERT, en un escenario real mucho más grande, donde podría suceder que una o algunas de ellas tengan errores como los que vimos.

Si no tenemos un correcto uso de manejo de errores (error handling), imagina el trabajo de debug para encontrar cúal era el origen de la falla. Además ¿es realmente la reacción que queremos en nuestros datos? ¿que cuando haya una falla, se aplique todo menos las partes con error?

Posiblemente la respuesta sea sí, sin embargo es importante considerar que si queremos mantener total integridad de la información, deberíamos tener en mente la propiedad de ATOMICIDAD en manejo de base de datos y planificar ejecuciones completas todo el tiempo.

¿Cómo garantizamos esta ejecución completa? XACT_ABORT

Como decíamos al principio de este post, la opción XACT_ABORT está definida en modo OFF por defecto. Lo primero que debemos hacer cambiar esto.

xact-abort-sql-server-demo3

El mensaje de la ejecución es el mismo, sin embargo notamos una pequeña diferencia en comparación del anterior.

xact-abort-sql-server-demo4
Luego del error no continúa con el resto de las ejecuciones

Si ejecutamos nuevamente el SP que nos muestra todos los registros.

xact-abort-sql-server-demo5
Solo están los registros correctos. Ninguno del bloque de INSERTs llegó a la tabla

¿Cuál es entonces la mejor manera de trabajar?

  • Primero analizar qué es lo que necesita mi negocio y cómo espera que los programas reaccionen.
  • Contar simpre con un buen manejo de errores.
  • Cuando necesitamos mantener la integridad de nuestras transacciones, es por esta razón que podemos considerar como una buena práctica, mantener la opción XACT_ABORT en ON para así ante cualquier error, automáticamente SQL Server aborte la transacción y tengamos al rollback garantizado.

Pablo Javier Fernández

www.datoptim.com
I love working on SQL Server Performance Tuning and finding the origin of the problems. Music and SQL Server passionate.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Close search

Carrito

Volver arriba