About Me

My photo
Mumbai, Maharastra, India
He has more than 7.6 years of experience in the software development. He has spent most of the times in web/desktop application development. He has sound knowledge in various database concepts. You can reach him at viki.keshari@gmail.com https://www.linkedin.com/in/vikrammahapatra/ https://twitter.com/VikramMahapatra http://www.facebook.com/viki.keshari

Search This Blog

Thursday, January 9, 2014

Some witty finding on Nested Transaction II: Partial Rollback with Savepoint


Here in this article we will see how we can rollback a portion of transaction keeping other part as it is for commit. For revelation we are again taking the same EMP table, let see first, how many records are present in it.
  
select * from emp
emp_id      ename      dept_id
----------- ---------- -----------
1           neha       1
2           richa      1
3           sidhika    2
4           Sneha      1
6           Kavita     3

(5 row(s) affected)

Now I am writing a block which is nested by two transaction, in the inner transaction after inserting record with emp_id 8, I m trying to rollback the inner transaction while keeping the first (outer) transaction as it is for commit.

set nocount on
go
begin tran
      insert into emp values(7,'Sanjana',2)
      begin tran
            insert into emp values(8,'Monica',2)
            rollback tran
commit tran

Msg 3902, Level 16, State 1, Line 6
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.

select * from emp
emp_id      ename      dept_id
----------- ---------- -----------
1           neha       1
2           richa      1
3           sidhika    2
4           Sneha      1
6           Kavita     3

(5 row(s) affected)

Here we saw, the first call to ROLLBACK TRAN in inner transaction rollback both the transaction the outer and inner one. So there must be no insert into the table emp. We can also check this using @@trancount.

Let’s print @@trancount in the same script.

set nocount on
go
begin tran
      insert into emp values(7,'Sanjana',2)
      print 'Trancount : ' + cast(@@trancount as varchar)
      begin tran
            insert into emp values(8,'Monica',2)
            print 'Trancount : ' + cast(@@trancount as varchar)
            rollback tran
      print'Trancount : ' + cast(@@trancount as varchar)
commit tran

Trancount : 1
Trancount : 2
Trancount : 0
Msg 3902, Level 16, State 1, Line 9
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.

So after the rollback fired, both the opened transaction closed and we get @@trancount as 0.

Now let’s define the transaction with name so that we can explicitly mention which transaction to rollback

set nocount on
go
begin tran   outerTran
      insert into emp values(7,'Sanjana',2)
      print 'Trancount : ' + cast(@@trancount as varchar)
      begin tran InnerTran
            insert into emp values(8,'Monica',2)
            print 'Trancount : ' + cast(@@trancount as varchar)
            rollback tran  InnerTran
      print'Trancount : ' + cast(@@trancount as varchar)
commit tran outerTran

Trancount : 1
Trancount : 2
Msg 6401, Level 16, State 1, Line 7
Cannot roll back InnerTran. No transaction or savepoint of that name was found.
Trancount : 2

select * from emp
emp_id      ename      dept_id
----------- ---------- -----------
1           neha       1
2           richa      1
3           sidhika    2
4           Sneha      1
6           Kavita     3
7           Sanjana    2
8           Monica     2

So we can rollback on inner transaction has no effect and the out transaction committed both the insert in spite of having rollback on second transaction.

I am deleting employee with emp_id 7 and 8

delete emp where emp_id=7 or emp_id=8

Here I am using Savepoint, this will allow to rollback some part of transaction leaving other part as it is for commit. One more thing, one can’t use savepoint without transaction. Let’s see, how we are using savepoint in our earlier code..

set nocount on
go
begin tran   outerTran
      insert into emp values(7,'Sanjana',2)
      print 'Trancount : ' + cast(@@trancount as varchar)
      begin tran InnerTran
            save tran ManishPoint
            insert into emp values(8,'Monica',2)
            print 'Trancount : ' + cast(@@trancount as varchar)
            rollback tran  ManishPoint
      print'Trancount : ' + cast(@@trancount as varchar)
commit tran outerTran

select * from emp

emp_id      ename      dept_id
----------- ---------- -----------
1           neha       1
2           richa      1
3           sidhika    2
4           Sneha      1
6           Kavita     3
7           Sanjana    2 

Now you can see the inner transaction which was trying to insert employee with id 8 get rollbacked and leaving other part of transaction as it is to commit.

Watch your thought, they became logic
Watch your logic, they became code
Watch your code, they became program
Watch your program, crop up new thought

SDLC…cont..

Post Reference: Vikram Aristocratic Elfin Share

No comments:

Post a Comment