2011-01-06 17 views
6

Si tengo un procedimiento almacenado que ejecuta otro procedimiento almacenado varias veces con diferentes argumentos, ¿es posible hacer que cada una de estas llamadas se confirme independientemente de las demás?¿Cómo puedo asegurarme de que las transacciones anidadas se confirman de forma independiente?

En otras palabras, si las dos primeras ejecuciones del procedimiento anidado tienen éxito, pero la tercera falla, ¿es posible preservar los resultados de las dos primeras ejecuciones (y no hacerlas retroceder)?

he un procedimiento definido almacenado algo como esto en SQL Server 2000:

CREATE PROCEDURE toplevel_proc .. 
AS 
BEGIN 

     ... 

     while @row_count <= @max_rows 
    begin 
     select @parameter ... where rownum = @row_count 
     exec nested_proc @parameter 
     select @row_count = @row_count + 1 
    end 

END 

Respuesta

6

En primer lugar, there is no such thing as a nested transaction in SQL Server

Sin embargo, puede utilizar SAVEPOINTs según este ejemplo (demasiado tiempo para reproducir aquí lo siento) del usuario compañero SO Remus Rusanu

Editar: AlexKuznetsov mencionó (sin embargo, borró su respuesta) que esto no funcionará si una transacción está condenada al fracaso. Esto puede suceder con SET XACT_ABORT ON o algunos errores de activación.

3

De BOL:

ROLLBACK transacción sin un savepoint_name o transaction_name rollos de nuevo al principio de la transacción . Al anidar las transacciones , esta misma instrucción revierte todas las transacciones internas a la instrucción BEGIN TRANSACTION más externa.

también encontré la siguiente desde otro hilo here:

Tenga en cuenta que las transacciones de SQL Server realmente no están anidados en la forma en que podría pensar. Una vez que se inicia una transacción explicto , un BEGIN TRAN subsiguiente incrementa @@ TRANCOUNT mientras que un COMMIT disminuye el valor. Toda la transacción externa es comprometida cuando un COMPROMISO da como resultado cero @@ TRANCOUNT. Pero un ROLLBACK sin un punto de rescate revierte todo el trabajo , incluida la transacción más externa .

Si necesita anidada comportamiento de la transacción , tendrá que utilizar SAVE transacción en lugar de COMENZAR TRAN y uso ROLLBACK TRAN [savepoint_name] en lugar de ROLLBACK TRAN.

Así que parece posible.

+1

"usar ROLLBACK TRAN en lugar de ROLLBACK TRAN" ?? – Greg

+0

@Greg - gracias por señalar eso. El texto que cité usó corchetes angulares alrededor del texto 'savepoint_name' y eso causó que el motor de marcado SO ocultara el texto. He editado el texto para usar corchetes. – Tony

+0

¡Gracias por corregirlo! – Greg

Cuestiones relacionadas