我想要对这个回答进行澄清 -> 嵌套的存储过程包含TRY CATCH ROLLBACK模式?
下面是来自上述链接的代码示例。
假设它是从启动事务的旧存储过程中调用的。在这种情况下,此过程将不会启动自己的事务,但会更改调用的XACT_ABORT状态。
因此,我有几个问题:
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
假设它是从启动事务的旧存储过程中调用的。在这种情况下,此过程将不会启动自己的事务,但会更改调用的XACT_ABORT状态。
因此,我有几个问题:
- XACT_ABORT仅适用于当前过程还是整个调用堆栈?
- 如果我想重构一个过程以使用SET XACT_ABORT ON,是否需要与SET XACT_ABORT OFF配对?这是传统代码中最安全的方法吗?
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