我读了这个Stackoverflow问题 Nested stored procedures containing TRY CATCH ROLLBACK pattern?
我需要澄清交易模板 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 开始交易
IF @starttrancount = 0 提交交易
我是交易的新手,用例子解释会非常有帮助。 谢谢:))
答案 0 :(得分: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变量。