SQLException - Transaction BEGIN / COMMIT mismatch

Chris Ballance picture Chris Ballance · Sep 16, 2010 · Viewed 21.8k times · Source

Have you encountered this exception for a stored procedure which does indeed have a balanced transaction block?

I double-checked the stored procedure and it has exactly one TRANSACTION BEGIN and cooresponding TRANSACTION END

Error logged

SqlException - Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.  The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION. - Delete failed - stack:    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)     at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)     at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)     at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)     at System.Data.SqlClient.S ... [Rest of stack trace truncated by logging system]`

Additional Info

The stored procedure does contain EXEC calls to another stored procedure. Would a mismatched transaction pair here cause the error to be surfaced in this way?

Update It turns out that there was a violation of a foreign key constraint within the nested stored procedure. The outer transaction did not include a Try/Catch block and had SET XACT_ABORT ON specified, which did not properly handle either a commit or rollback. Also added a check for @@TransactionCount > 0 before attempting a rollback

Answer

Remus Rusanu picture Remus Rusanu · Sep 16, 2010

Yes it would. Each BEGIN increments @@trancount, each commit decrements it. Only when the count gets to 0 is the transaction really committed. Your procedure, as a caller, cannot control this. It is the job of the called procedures to behave properly and balance the BEGIN and COMMIT count, if any of the called procedures has a imbalance, you'll see this error.