views:

186

answers:

6

I want to call a SP from another SP. I know I can easily call it. But Problem is, if an error occurs in SP2 then I want to ROLLBACK SP1.

SP1
BEGIN Tran
[Some Code]
Call to SP2
[Some Code]

SP2
BEGIN TRAN
[Some Code]
[Error Comes]
ROLLBACK TRAN

This would rollback Tran in sp2 only. I want to RollBack SP1 as well, if an error occurs in sp2.

Any help would be appreciated.

+1  A: 

One possibility is to create SP2 with an @ErrorCode INT OUTPUT parameter which indicates whether the caller needs to rollback or commit.

devio
Or use return values.
erikkallen
+4  A: 

Try RAISERROR in SP2.

Tomalak
Can you please elaborate it.
vaibhav
Raising an error within SP2 should cause SP1 to rollback its transaction as well. Do you do a manual roll-back or an automatic one?
Tomalak
Its automatic, Using "Rollback Tran"
vaibhav
A: 

Create an output parameter in your second SP which is of type bit, indicating wether an error occured or not. Based on this, you can rollback SP 1.

Maximilian Mayerl
+2  A: 

Seems people have issues with other information sites...

The gist of it is that the parent procedure will through an exception when trying to perform a ROLLBACK as the child already has. The way around this is to have the parent check the @trancount before committing.

http://forums.asp.net/t/1259708.aspx

Create procedure [dbo].[parent]  as Begin Transaction Begin Try
    Exec Child End Try Begin Catch
    If @@Trancount > 0
        RollBack End Catch Commit 


Create procedure [dbo].[Child]  as Begin Transaction Begin Try
    --Do inserts here End Try Begin Catch
    If @@Trancount > 0
        RollBack
    RAISERROR('Error Occured',16,1) End Catch Commit
Jonathan
Thou shalt not link to this site from here. ;-)
Tomalak
can't see anything at your link.
No Refunds No Returns
Thanks, Can I use @@error to check the 'raised error'
vaibhav
yes, the error will be in @@error at the parent procedure.
Jonathan
A: 

you can use an error code like that (i m not writing the code just how do i do if i were you)

SP1
DECLARE ReturnVal
BEGIN TRAN
CODE
CALL SP1 ReturnVal output
IF ReturnVal=errorvalue
ROLLBACK TRAN

SP2
DECLARE ReturnVal output
BEGIN TRAN
CODE
ERROR
SET ReturnVal=errorVal
ROLLBACK
RETURN ReturnVal
fealin
+1  A: 

It doesn't sound like you need the nested transactions. Try controlling the commit/rollback with try blocks (psuedocode):

begin try
  begin trans
  do stuff
  call other sp
  do more stuff
  commit trans
end try
begin catch
  rollback trans
  do something here to report failure to app
end catch

If an error occurs anywhere within the try block, including withing the other sp, the control will pass to the catch block and rollback the transaction.

Ray
I think this is worth considering. But should'nt I use an output parameter, as others are saying.
vaibhav
@valbhav: Consider using both `RAISERROR` and `TRY...CATCH`...
Sung Meister
My scheme will catch errors 'raised' either by you or by the server. If you need to report some business error info from the second sp, you could call raiserror as others have suggested, which my try-catch thing would catch. Or you could use an output parameter to report the error. In that case, the try-catch will not help you and you will need to do an 'if' statement or something to test the returned value. Even so, trh try-catch is still nice to catch unexpected errors.
Ray