gpt4 book ai didi

sql-server - 在存储过程中使用 SAVE TRANSACTION SavePointName

转载 作者:行者123 更新时间:2023-12-01 23:31:04 27 4
gpt4 key购买 nike

我不清楚是否需要为我使用的每个 SP 使用不同的保存点名称 SAVE TRANSACTION

我可以总是使用例如SAVE TRANSACTION ProcedureSavePointROLLBACK TRANSACTION ProcedureSavePoint 即使更高级别的事务使用相同的保存点名称?

我的 SP(s) 签名如下:

ALTER PROCEDURE [dbo].[usp_MyTask]()
AS
BEGIN
DECLARE @iReturn int = 0

DECLARE @tranCount int = @@TRANCOUNT;
IF @tranCount > 0
SAVE TRANSACTION ProcSavePoint;
ELSE
BEGIN TRAN
...

IF <some condition>
BEGIN
@iReturn = 1
GOTO Undo
END

...

IF @tranCount = 0
COMMIT TRAN
RETURN

Undo:
IF @tranCount = 0 -- transaction started in procedure. Roll back complete transaction.
ROLLBACK TRAN;
ELSE
IF XACT_STATE() <> -1 ROLLBACK TRANSACTION ProcSavePoint;

RETURN @iReturn
END

希望我的问题很清楚。

最佳答案

从技术上讲,是的,您可以重复使用相同的保存点名称,它们会像多次调用 BEGIN TRAN 一样堆积起来,其中每次调用 COMMIT 只会递减计数器。意思是,如果您发出 SAVE TRANSACTION ProcSavePoint; 5 次,然后调用 ROLLBACK TRANSACTION ProcSavePoint; 2 次,在第三次调用 SAVE TRAN 之后和第四次调用之前,您仍将停留在事物所处的状态。

然而,这段代码在几个层面上存在问题:

  • 由于刚才提到的行为,在嵌套场景中,根据调用 GOTO Undo 的条件,如果您遇到调用嵌套 procs 5 级深,然后 5 级成功完成,然后 4 级完成的情况成功,但随后第 3 级决定转到“撤消”,它将执行 ROLLBACK TRANSACTION ProcSavePoint;,这只会回滚第五级。这让您处于糟糕的状态,因为目的是回滚到第 3 级开始时的状态。

    使用唯一的保存点名称可以纠正这一点。
  • 奇怪的是,您没有使用 TRY/CATCH 构造。你真的应该。如果您的逻辑决定基于非 SQL Server 错误的特定条件取消操作,您仍然可以通过调用 RAISERROR() 立即转到 CATCH 块来强制取消。或者,如果您不想将其作为错误处理,除了 GOTO undo/TRY 之外,您仍然可以执行 CATCH 方法。
  • 我不相信 XACT_STATE() 可以报告 -1/TRY 构造之外的 CATCH
  • 首先为什么要使用 Save Points?即使在 sub-proc 调用中发生错误,您是否遇到过外层可能会继续并最终 COMMIT 的情况?

    我最常使用的模板显示在我对 DBA.StackExchange 上的这个问题的回答中: Are we required to handle Transaction in C# Code as well as in Store procedure 。该模板只是在开始时检查事件事务(类似于您的方法),但如果存在事件事务,则不执行任何操作。所以永远不会有额外的 BEGIN TRAN 甚至 SAVE TRAN 被调用,只有外部(即使是应用程序代码)才会执行 COMMITROLLBACK

    只是为了指出这一点,因为它看起来像是您的代码与我在该链接答案中发布的内容之间的功能差异,但实际上并非如此:没有特别需要捕获 @@TRANCOUNT 的实际值,因为唯一的选项是 0> 0 ,除非在输入模板时 @@TRANCOUNT 已经 > 1,否则它将获得的最大值为 1(如果触发器和/或 INSERT INTO ... EXEC 增加,即使存在事件事务,也可能为 2)。在任何一种情况下,我对 BIT 使用 @InNestedTransaction 变量在功能/逻辑上等同于将 @@TRANCOUNT 存储在 INT 变量中,因为 SAVE TRAN 不会增加 @@TRANCOUNT
  • 关于sql-server - 在存储过程中使用 SAVE TRANSACTION SavePointName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35683880/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com