2009-11-28 10 views
6

He leído a través de MSDN en ROLLBACK TRANSACTION y nesting transactions. Si bien veo el punto de ROLLBACK TRANSACTION savepointname, no entiendo ROLLBACK TRANSACTION transactionname.¿Cuál es el sentido de "ROLLBACK TRANSACTION named_transaction"?

  1. sólo funciona cuando transactionname es la transacción más externa
  2. ROLLBACK siempre retrotrae la transacción completa "pila", excepto en el caso de savepointname

Básicamente, al leer la documentación, excepto en el caso de un punto guardado, ROLLBACK revierte todas las transacciones (a @@TRANCOUNT=0). La única diferencia que veo es este fragmento:

Si una declaración transaction_name ROLLBACK TRANSACTION usando el nombre de la transacción externa se ejecuta en cualquier nivel de un conjunto de anidados transacciones, todos los transacciones anidadas están retrocediendo. Si se ejecuta una instrucción ROLLBACK WORK o ROLLBACK TRANSACTION sin un parámetro transaction_name en cualquier nivel de un conjunto de transacciones anónimas , revierte todas las transacciones anidadas, incluida , la transacción más externa.

De la lectura, esto me sugiere que al deshacer una transacción con nombre (que debe ser el nombre de la transacción más externa), solo se revertirán las transacciones anidadas. Esto daría algún significado para revertir una transacción con nombre. Así que he creado una prueba:

CREATE TABLE #TEMP (id varchar(50)) 

INSERT INTO #TEMP (id) VALUES ('NO') 
SELECT id AS NOTRAN FROM #TEMP 
SELECT @@TRANCOUNT AS NOTRAN_TRANCOUNT 

BEGIN TRAN OUTERTRAN 

INSERT INTO #TEMP (id) VALUES ('OUTER') 
SELECT id AS OUTERTRAN FROM #TEMP 
SELECT @@TRANCOUNT AS OUTERTRAN_TRANCOUNT 

BEGIN TRAN INNERTRAN 

INSERT INTO #TEMP (id) VALUES ('INNER') 
SELECT id AS INNERTRAN FROM #TEMP 
SELECT @@TRANCOUNT AS INNERTRAN_TRANCOUNT 

ROLLBACK TRAN OUTERTRAN 

IF @@TRANCOUNT > 0 ROLLBACK TRAN 

SELECT id AS AFTERROLLBACK FROM #TEMP 
SELECT @@TRANCOUNT AS AFTERROLLBACK_TRANCOUNT 

DROP TABLE #TEMP 

resultado en (todo "fila de X (s) afectado" cosas eliminado)

NOTRAN 
-------------------------------------------------- 
NO 

NOTRAN_TRANCOUNT 
---------------- 
0 

OUTERTRAN 
-------------------------------------------------- 
NO 
OUTER 

OUTERTRAN_TRANCOUNT 
------------------- 
1 

INNERTRAN 
-------------------------------------------------- 
NO 
OUTER 
INNER 

INNERTRAN_TRANCOUNT 
------------------- 
2 

AFTERROLLBACK 
-------------------------------------------------- 
NO 

AFTERROLLBACK_TRANCOUNT 
----------------------- 
0 

en cuenta que hay ninguna diferencia a la salida cuando cambio

ROLLBACK TRAN OUTERTRAN 

simplemente

ROLLBACK TRAN 

Entonces, ¿cuál es el punto de ROLLBACK TRANSACTION named_transaction?

Respuesta

5

Guardar puntos es exactamente lo que su nombre implica: 'guardar puntos' en la secuencia de registro. La secuencia de registro es siempre lineal. Si revierte a un punto de guardado, restituye todo lo que hizo su transacción entre su posición de registro actual y el punto de guardado. Tenga en cuenta su ejemplo: se crea

LSN 1: BEGIN TRAN OUTERTRAN 
LSN 2: INSERT INTO ... 
LSN 3: BEGIN TRAN INNERTRAN 
LSN 4: INSERT INTO ... 
LSN 5: ROLLBACK TRAN OUTERTRAN 

En Número de secuencia (LSN) 1 OUTERTRAN el punto de guardado. El primer INSERT crea LSN 2. Luego INNERTRAN crea un punto de guardado con LSN 3. El segundo INSERT crea un nuevo LSN, 4. El ROLLBACK OUTERTRAN es equivalente a 'ROLLBACK log hasta el LSN 1'. No puede 'omitir' porciones del registro, por lo que debe deshacer cada operación en el registro hasta que se pulse el LSN 1 (cuando se creó el punto de guardado OUTERTRAN).

Por otro lado, si en la última operación emitiría ROLLBACK INNERTRAN, el motor retrocedería hasta el LSN 3 (donde se insertó el punto de guardado 'INNERTRAN' en el registro) preservando así LSN 1 y LSN 2 (es decir .el primer INSERT).

Para obtener un ejemplo práctico de puntos guardados, vea Exception handling and nested transactions.

+0

Remus, gracias. Estoy viendo tu enlace ahora ... –

+0

OK, veo lo que has hecho. Sin embargo, todavía tengo curiosidad sobre mi punto original. Obtengo puntos de guardado y su valor, pero todavía estoy confundido por revertir el nombre de una transacción (no guardar punto). Una nota importante, aparentemente no puedes ROLLBACK una transacción interna. Por ejemplo, ROLLBACK TRAN INNERTRAN da como resultado un error, "No se puede deshacer INNERTRAN. No se encontró ninguna transacción ni se guardó el nombre de ese nombre". Este punto (sobre la reversión de las transacciones anidadas llamadas no autorizadas) se encuentra en los enlaces de documentación que mencioné en el OP. –

+3

'Para retroceder a INNERTRAN necesita usar la sintaxis 'SAVE TRANSACTION INNERTRAN' que crea un verdadero punto de guardado (en lugar de una transacción con nombre). Las transacciones con nombre son principalmente para escenarios de recuperación ('RESTORE WITH STOPAT OUTERTRAN') –

Cuestiones relacionadas