【发布时间】:2011-04-18 18:56:31
【问题描述】:
我想澄清一下这个答案 -> Nested stored procedures containing TRY CATCH ROLLBACK pattern?
以下是来自上述链接的代码示例
1 CREATE PROCEDURE [Name]
2 AS
3 SET XACT_ABORT, NOCOUNT ON
4
5 DECLARE @starttrancount int
6
7 BEGIN TRY
8 SELECT @starttrancount = @@TRANCOUNT
9
10 IF @starttrancount = 0
11 BEGIN TRANSACTION
12
13 [...Perform work, call nested procedures...]
14
15 IF @starttrancount = 0
16 COMMIT TRANSACTION
17 END TRY
19 BEGIN CATCH
20 IF XACT_STATE() <> 0 AND @starttrancount = 0
21 ROLLBACK TRANSACTION
22 RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
23 END CATCH
24 GO
假设它是从启动事务的旧存储过程中调用的。 在这种情况下,这个 proc 不会启动它自己的事务,但会改变调用的 XACT_ABORT 状态。
所以,我有几个问题。
- 当前 XACT_ABORT 是否处于活动状态 仅 proc,或整个通话 堆栈?
- 如果我想重构一个 proc 来使用 SET XACT_ABORT ON,我需要配对吗 SET XACT_ABORT OFF?对于遗留代码,这是最安全的方法吗?
以下是修改后的示例,它有条件地打开 XACT_ABORT 并将其与在 proc 退出时关闭它配对
CREATE PROCEDURE [Name]
AS
SET NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN
SET XACT_ABORT ON
BEGIN TRANSACTION
END
[...Perform work, call nested procedures...]
IF @starttrancount = 0
BEGIN
COMMIT TRANSACTION
SET XACT_ABORT OFF
END
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
BEGIN
ROLLBACK TRANSACTION
SET XACT_ABORT OFF
END
RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO
【问题讨论】:
标签: sql-server