I read this Stackoverflow question Nested stored procedures containing TRY CATCH ROLLBACK pattern?
I'm in need of clarification on Transaction template what gbn have answered. I couldn't comment and ask there.
CREATE PROCEDURE [Name]
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
[...Perform work, call nested procedures...]
IF @starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION
RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO
My Question is!
Why to use ?
SELECT @starttrancount = @@TRANCOUNT , rather than using @@TRANCOUNT directly??
and why to check this?
IF @starttrancount = 0 BEGIN TRANSACTION
IF @starttrancount = 0 COMMIT TRANSACTION
I'm new to transaction , explanation with example would be so helpfull. Thanks :)
IF @starttrancount = 0 BEGIN TRANSACTION IF @starttrancount = 0 COMMIT TRANSACTION
These are used because, the @starttrancount guaranteed to let only the outer most stored procedure to use transaction, so that only one transaction exists.
Example: We want to execute outer most procedure, then the transaction must be used in outer most procedure only.
Outer Stored Procedure
CREATE PROCEDURE sp_outer
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT -- Initially @@TRANSCOUNT =0
IF @starttrancount = 0
BEGIN TRANSACTION -- @@TRANSCOUNT =1
EXEC sp_inner -- Inner Procedure is called with @@TRANSCOUNT =1
-- so that Transaction in inner procedure will not be used.
-- Per Transaction is exists.
IF @starttrancount = 0
COMMIT TRANSACTION -- @@TRANSCOUNT = 0
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION -- If Error occurs Rollback takes place.
RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO
2.Inner Stored Procedure
CREATE PROCEDURE sp_inner
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT -- @@TRANCOUNT =1
IF @starttrancount = 0
BEGIN TRANSACTION -- Skipped
[...Perform work, call nested procedures...]
IF @starttrancount = 0
COMMIT TRANSACTION -- Skipped
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION -- if Error Caught Roll back does not happen here
RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc] -- Error thrown to outer stored procedure.
END CATCH
GO
why SELECT @starttrancount = @@TRANCOUNT , rather than using @@TRANCOUNT directly??
Since @@TRANSCOUNT scope exists in both the stored procedures, for maintaining values within the procedure's scope @starttrancount variable is used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.