2013-09-27 75 views
1

澄清我看到这个问题#1 Nested stored procedures containing TRY CATCH ROLLBACK pattern?需要对交易SQL SERVER

我需要澄清的交易模板什么GBN已经回答了我。 我无法评论,并在那里问。

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 

我的问题是!

为什么要使用?

SELECT @starttrancount = @@ TRANCOUNT,而不是直接使用@@ TRANCOUNT?

以及为什么要检查这个?

IF @starttrancount = 0 BEGIN TRANSACTION

IF @starttrancount = 0 COMMIT TRANSACTION

我是新来的交易,与实例详解会如此有益的。 谢谢:)

回答

0
IF @starttrancount = 0 BEGIN TRANSACTION 

IF @starttrancount = 0 COMMIT TRANSACTION 

这些都是因为使用,保证让只有最外面的存储过程@starttrancount使用的交易,因此,只有一个事务存在。

示例:我们要执行最外层的过程,那么事务只能用于最外层的过程。

外部存储过程

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存储过程

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 

为什么SELECT @starttrancount = @@ TRANCOUNT,而不是直接使用 @@ TRANCOUNT ??

由于存在于两个存储过程@@ TRANSCOUNT范围,对于被使用的程序的范围 @starttrancount可变内保持的值。