2013-09-27 103 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可變內保持的值。