Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rollback the inner transaction of nested transaction

suppose I have following sql statement in sql server 2008:

BEGIN TRANSACTION     SqlStatement1     EXEC sp1     SqlStatement3 COMMIT TRANSACTION 

The code of sp1

BEGIN TRANSACTION SqlStatement2 ROLLBACK TRANSACTION 

My question is: Is SqlStatement3 actually executed?

like image 624
Niyoko Avatar asked Sep 17 '12 09:09

Niyoko


People also ask

What happens to a nested transaction when the outer transaction is rolled back?

If the outer transaction is committed, the inner nested transactions are also committed. If the outer transaction is rolled back, then all inner transactions are also rolled back, regardless of whether or not the inner transactions were individually committed.

What happens when a ROLLBACK happens in inside a nested stored procedure?

Whenever the rollback is called in a nested transaction it rolls back all the transactions in the hierarchy starting from the outermost transaction.

What happens when you commit a transaction What if the transaction is nested within another transaction?

With a nested transaction, a commit does not write any changes to disk, except for the top level transaction. A rollback, however works regardless of the level of the transaction, so yes, it will roll the inner transaction back.


1 Answers

SQL Server doesn't really support nested transactions. There is only one transaction at a time.

This one transaction has a basic nested transaction counter, @@TRANCOUNT. Each consecutive begin transaction increments the counter by one, each commit transaction reduces it by one. Only the commit that reduces the counter to 0 really commits the one transaction.

A rollback transaction undoes the one transaction and clears @@TRANCOUNT.

In your case, the funny result is that SqlStatement3 is run outside a transaction! Your final commit will throw an "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION" exception, but the effects of SqlStatement3 are permanent.

For example:

create table #t (col1 int) insert #t (col1) values (1) BEGIN TRANSACTION update #t set col1 = 2 -- This gets rolled back BEGIN TRANSACTION update #t set col1 = 3 -- This gets rolled back too ROLLBACK TRANSACTION update #t set col1 = 4 -- This is run OUTSIDE a transaction! COMMIT TRANSACTION -- Throws error select col1 from #t 

Prints 4. Really. :)

like image 157
Andomar Avatar answered Sep 20 '22 21:09

Andomar