2012-07-10 22 views
6
USE AdventureWorks; 
GO 
BEGIN TRANSACTION; 
GO 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 10; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 11; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 12; 
GO 
COMMIT TRANSACTION; 
GO 

¿Qué sucede si falla la primera instrucción de eliminación? ¿Se ejecutarán las declaraciones de eliminación 2ª y 3ª? El ejemplo no tiene ningún manejo de errores, ¿dejará una transacción abierta en el caso de una excepción o SQL Server revertirá la transacción automáticamente? Abrir transacción = recursos bloqueados, ¿verdad?¿Se requiere ROLLBACK TRANSACTION?

Estoy decidiendo si debo aplicar TRY ... CATCH a procedimientos almacenados que usan transacciones.

Conozco set xact_abort on, pero quiero saber qué pasa sin él.

Esto es lo que he encontrado en documentos - Control de Transacciones (motor de base de datos):

Si un error impide la finalización con éxito de una transacción, SQL Server revierte automáticamente la transacción y libera todos los recursos en poder de la transacción

Sin embargo, he leído en otras publicaciones que la retrotracción automática no se activa.

+0

Sí, use try ... catch. – Ben

Respuesta

11

En su ejemplo, sin el uso de SET XACT_ABORT ON, la operación continuará y confirmar, incluso si la primera sentencia falla. En el texto que citó, las palabras clave son if an error **prevents** the successful completion of a transaction y un error en la declaración DELETE no impide que la transacción se complete.

Un ejemplo de un error que causaría una reversión automática es si la conexión a la base de datos se cortó en el medio de una transacción. Más abajo en la MSDN article al que hizo referencia dice:

Si un error de sentencia en tiempo de ejecución (como una violación de restricción) se produce en un lote, el comportamiento por defecto en el motor de base de datos es rodar volver solamente la afirmación de que generó el error. Puede cambiar este comportamiento utilizando la instrucción SET XACT_ABORT. Después de ejecutar SET XACT_ABORT ON , cualquier error de instrucción en tiempo de ejecución provoca una reversión automática de la transacción actual. Los errores de compilación, como los errores de sintaxis, son no afectados por SET XACT_ABORT.

Siempre es una buena idea utilizar el manejo de errores para detectar errores y volver atrás si es necesario.

+0

Por lo tanto, revertirá la primera instrucción de eliminación fallida, luego comenzará a ejecutar la segunda, y luego de la misma manera, ¿la tercera? Y al final bajará a la declaración de compromiso? Eso significa que el error en una sola instrucción no detendrá la ejecución del lote, ¿verdad? –

+0

Eso es exactamente correcto. Además, actualicé mi respuesta para (con suerte) ser un poco más claro :) –

5

prefiero para controlar el proceso de forma manual:

BEGIN TRY 
BEGIN TRAN 

    -- do work 

COMMIT 
END TRY 
BEGIN CATCH 
    ROLLBACK 
    RAISERROR (...) 
END CATCH 
GO