Solución:
Puedo pensar en algunos escenarios para considerar al tratar con @@trancount
:
- La transacción actual se llamó desde otro procedimiento almacenado que tenía su propia transacción
- La transacción actual fue llamada por algún código .NET con su propia transacción
- La transacción actual es la única transacción
Creo que el manejo de excepciones y las transacciones anidadas de Remus Rusanu manejan todas estas posibilidades.
Para responder a la pregunta, el momento de hacer un @@ trancount es si el código en el medio podría haber realizado ya la confirmación o reversión de la transacción que inició. Entonces, si está llamando a procedimientos almacenados, por ejemplo, realice las comprobaciones al final.
Por cierto, en lugar de hacer un if @@ trancount> 0, sugeriría que es mejor verificar el @@ trancount al comienzo de su bloque de código, y luego ver si el conteo ha aumentado al final, en cuyo caso haga el commit o rollback, dependiendo de try / catch.
Particularmente si está en un disparador, porque @@ trancount siempre será 1 allí, por lo que simplemente hacer un @@ trancount> 0 podría causar un error.
Pero incluso si su código está solo en un procedimiento almacenado, suponiendo que fue llamado por otro procedimiento que tiene una transacción abierta, si su código tiene errores y se revierte, entonces el procedimiento almacenado externo también tendrá su transacción revertida (consulte https: //www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-2630-nested-transactions-are-real/).
Entonces
COMIENCE A IMPRIMIR TRAN @@ TRANCOUNT
COMIENCE A IMPRIMIR TRAN @@ TRANCOUNT
ROLLBACK TRAN PRINT @@ TRANCOUNT
muestra 1 2 0
Básicamente, si el código en el medio llama a otros procedimientos, debe realizar la verificación IF @@ TRANCOUNT.