Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0

I have an Insert stored procedure which will feed data to Table1 and get the Column1 value from Table1 and call the second stored procedure which will feed the Table2.

But when I call The second stored procedure as:

Exec USPStoredProcName 

I get the following error:

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.

I have read the answers in other such questions and am unable to find where exactly the commit count is getting messed up.

like image 384
Vignesh Kumar A Avatar asked Feb 21 '14 09:02

Vignesh Kumar A


People also ask

How do I count transactions in SQL Server?

@@TRANCOUNT (Transact-SQL) Returns the number of BEGIN TRANSACTION statements that have occurred on the current connection.

What are transactions in SQL?

A transaction is a logical unit of work that contains one or more SQL statements. A transaction is an atomic unit. The effects of all the SQL statements in a transaction can be either all committed (applied to the database) or all rolled back (undone from the database).

What is rollback transaction in SQL Server?

You can use ROLLBACK TRANSACTION to erase all data modifications made from the start of the transaction or to a savepoint. It also frees resources held by the transaction. This does not include changes made to local variables or table variables. These are not erased by this statement.


Video Answer


1 Answers

If you have a TRY/CATCH block then the likely cause is that you are catching a transaction abort exception and continue. In the CATCH block you must always check the XACT_STATE() and handle appropriate aborted and uncommitable (doomed) transactions. If your caller starts a transaction and the calee hits, say, a deadlock (which aborted the transaction), how is the callee going to communicate to the caller that the transaction was aborted and it should not continue with 'business as usual'? The only feasible way is to re-raise an exception, forcing the caller to handle the situation. If you silently swallow an aborted transaction and the caller continues assuming is still in the original transaction, only mayhem can ensure (and the error you get is the way the engine tries to protect itself).

I recommend you go over Exception handling and nested transactions which shows a pattern that can be used with nested transactions and exceptions:

create procedure [usp_my_procedure_name] as begin     set nocount on;     declare @trancount int;     set @trancount = @@trancount;     begin try         if @trancount = 0             begin transaction         else             save transaction usp_my_procedure_name;          -- Do the actual work here  lbexit:         if @trancount = 0             commit;     end try     begin catch         declare @error int, @message varchar(4000), @xstate int;         select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();         if @xstate = -1             rollback;         if @xstate = 1 and @trancount = 0             rollback         if @xstate = 1 and @trancount > 0             rollback transaction usp_my_procedure_name;          raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;     end catch end go 
like image 131
Remus Rusanu Avatar answered Sep 28 '22 10:09

Remus Rusanu