gpt4 book ai didi

sql - 多个开始事务

转载 作者:行者123 更新时间:2023-12-04 23:28:06 24 4
gpt4 key购买 nike

我今天遇到了这个意外,想知道一些事情。基本代码设置是

Begin Transaction 
Update Table
set column to value

Begin transaction
Update Table
set column to value

我玩了一点,发现你不能在回滚之后进行提交,但是你可以在回滚之前进行提交,但是回滚否定了提交。我想我的问题是,这有什么目的/用途吗?除了让我的 DBA 因代码错误而扇我耳光之外,我没有看到其他任何东西哈哈

最佳答案

简短的回答是,嵌套事务设计背后的意图是允许您编写可重用的过程(或代码块),其中可以自动处理以下两种情况,而无需为两种情况编写不同的代码:

  • 如果尚未开始交易,您可以开始和结束交易。
  • 或者,如果交易已经在进行中,那么您只需参与正在进行的交易即可。

假设您喜欢以事务方式编写所有可重用过程,如下所示(伪代码):

create procedure Foo
begin transaction

perform DML 1
perform DML 2
perform DML 3
-- other stuff

commit transaction
end procedure

create procedure Blah
begin transaction

perform DML 1
perform DML 2
perform DML 3
-- other stuff

commit transaction
end procedure

但是现在,假设您现在需要 Blah 过程来合并 Foo 的功能。显然,您不想将 Foo 的内容复制粘贴到 Blah 中。为了可重用性,对 Foo 的简单调用更有意义,如下所示:

create procedure Blah
begin transaction

perform DML 1
perform DML 2

-- include a call to Foo here
Foo();

perform DML 3
-- other stuff

commit transaction
end procedure

在上述情况下,如果不更改 Foo 的代码,对 Blah 的调用仍将表现为一个大事务,这可能是您想要的。

正是在这种情况下,inner commits 实际上并没有做任何事情。他们实际上只是为了标记在那之前一切都很好。但真正的提交只有在外部事务提交所有内容时才会发生。

想象一下,如果每个提交实际上都提交了事务,那么,为了确保您不会破坏外部事务,您必须在每个过程的开头添加额外的条件来检查事务是否已经启动,并且仅如果没有找到,则启动一个。因此,每个过程都必须像这样进行编码,以确保在其他过程中调用它是安全的:

create procedure Foo
didIStartATransaction = false
if @@trancount = 0 then
begin transaction
didIStartATransaction = true
end if

perform DML 1
perform DML 2
perform DML 3
-- other stuff

if didIStartATransaction then
commit transaction
end if
end procedure

create procedure Blah
didIStartATransaction = false
if @@trancount = 0 then
begin transaction
didIStartATransaction = true
end if

perform DML 1
perform DML 2
perform DML 3
-- other stuff

if didIStartATransaction then
commit transaction
end if
end procedure

也就是说,如果其中一个过程忘记对称启动和提交事务,嵌套事务仍然很危险。

就个人而言,我更喜欢在我的任何程序中都没有任何事务控制语句,而只让调用代码管理事务。这样我感觉更安全。

关于sql - 多个开始事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31277829/

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