Lo primero para empezar el trabajo con SQL Server es preparar el ambiente. La instalación…
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.
Si ejecutamos el SP que nos muestra todos los registros.
¿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.
El mensaje de la ejecución es el mismo, sin embargo notamos una pequeña diferencia en comparación del anterior.
Si ejecutamos nuevamente el SP que nos muestra todos los registros.
¿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.