When it's necessary to check @@trancount > 0 in try catch block?
I can think of a few scenarios to consider when dealing with @@trancount
:
- The current transaction was called from another stored procedure which had its own transaction
- The current transaction was called by some .NET code with its own transaction
- The current transaction is the only transaction
I believe Remus Rusanu's Exception handling and nested transactions handles all these possibilities.
To answer the question - the time to do a @@trancount is if the code in the middle could potentially have already performed the commit or rollback of the transaction you started. So if you are calling stored procedures for example - then perform the checks at the end.
Incidentally rather than doing an if @@trancount>0 I would suggest it is better to check the @@trancount at the start of your block of code, and then see if the count has gone up by the end, in which case do the commit or rollback, depending on try/catch.
Particularly if you are in a trigger, because the @@trancount will always be 1 there, so just doing a @@trancount>0 could cause an error.
But even if your code is just in a stored procedure, supposed it was called by another procedure that itself has an open transaction, if your code errors and rolls back, then the outer stored procedure will have its transaction rolled back also (see https://www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-2630-nested-transactions-are-real/).
So
BEGIN TRAN PRINT @@TRANCOUNT
BEGIN TRAN PRINT @@TRANCOUNT
ROLLBACK TRAN PRINT @@TRANCOUNT
shows 1 2 0
So basically - if the code in the middle is calling other procedures, you need to perform the IF @@TRANCOUNT check.