Tengo un procedimiento almacenado que necesita establecer un punto de guardado para que pueda, en ciertas circunstancias, deshacer todo lo que hizo y devolver un código de error a la persona que llama , o lo acepta/confirma y devuelve el éxito a la persona que llama. Pero necesito que funcione si la persona que llama ya inició una transacción o no. El documento es extremadamente confuso sobre este tema. Esto es lo que creo que funcionará, pero no estoy seguro de todas las ramificaciones.GUARDAR TRANSACCIÓN vs COMIENZO TRANSACCIÓN (Servidor SQL) cómo anidar transacciones muy bien
Lo que pasa es que este Stored Procedure (SP)
es llamado por otros. Así que no sé si iniciaron una transacción o no ... Incluso si requiero que los usuarios inicien una transacción para usar mi SP, aún tengo dudas sobre el uso correcto de Save Points
...
Mi SP probará si una transacción está en curso, y si no, comience una con BEGIN TRANSACTION
. Si una transacción ya está en progreso, creará un punto de guardado con SAVE TRANSACTION MySavePointName
, y guarde el hecho de que esto es lo que hice.
Luego, si tengo que retrotraer mis cambios, si hice un BEGIN TRANSACTION
antes, entonces lo haré ROLLBACK TRANSACTION
. Si hice el punto de guardado, entonces lo haré ROLLBACK TRANSACTION MySavePointName
. Este escenario parece funcionar bien.
Aquí es donde me confundo un poco: si quiero mantener el trabajo que he hecho, si comencé una transacción ejecutaré COMMIT TRANSACTION
. Pero si creé un punto de guardado? Probé COMMIT TRANSACTION MySavePointName
, pero entonces la persona que llama intenta cometer su transacción y obtiene un error:
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Así que me pregunto entonces - un punto de guardado se puede deshacer (que funciona: ROLLBACK TRANSACTION MySavePointName
no va a hacer retroceder la persona que llama de transacción). Pero tal vez uno nunca necesita "comprometerlo"? Simplemente permanece allí, en caso de que necesite retroceder, pero desaparece una vez que la transacción original se ha comprometido (o revertido).
Si hay una "mejor" manera de "anidar" una transacción, por favor, arroje algo de luz también. No he descubierto cómo anidar con BEGIN TRANSACTION
, pero solo retrotrajo o confirmo mi transacción interna. Parece que ROLLBACK
siempre retrocederá a la transacción superior, mientras que COMMIT
simplemente decrementa @@trancount
.
Su hallazgo podría valer la pena publicar como respuesta. –
@Andriy Ok, eso es lo que hice, eliminé mi edición y la utilicé como respuesta. Gracias. –