gpt4 book ai didi

sql - 为什么 SQL Server 死锁受害者错误 (1205) 会结束其所有事务?

转载 作者:行者123 更新时间:2023-12-04 23:57:33 34 4
gpt4 key购买 nike

考虑以下两个表:

create table testDeadlockTable1 (
c1 int not null,
c2 int not null
)
create table testDeadlockTable2 (
c1 int not null,
c2 int not null
)

有了这些数据:

insert testDeadlockTable1 values (1, 1)
insert testDeadlockTable1 values (2, 2)
insert testDeadlockTable1 values (3, 3)
insert testDeadlockTable1 values (4, 4)

insert testDeadlockTable2 values (1, 1)
insert testDeadlockTable2 values (2, 2)
insert testDeadlockTable2 values (3, 3)
insert testDeadlockTable2 values (4, 4)

并考虑以下两个存储过程:

create proc testDeadlockTestA
as
begin tran

update testDeadlockTable1
set c1 = 3
where c2 = 1

waitfor delay '00:00:01' -- sleep 1 second

select c1
from testDeadlockTable2
where c2 = 3

commit tran
go
create proc testDeadlockTestB
as
begin tran

update testDeadlockTable2
set c1 = 5
where c2 = 2

waitfor delay '00:00:01' -- sleep 1 second

select c1
from testDeadlockTable1
where c2 = 4

commit tran
go

在一个查询 session 中,调用 testDeadlockTestA,然后在另一个 session 中立即调用 testDeadlockTestB。后一个 session 将被选为死锁牺牲品。

在两个 session 中,@@trancount 在结尾处适本地为 0。

现在用 begin tran 开始每个查询 session ,以便在调用存储过程时 @@trancount 为 1。因此,死锁应该发生在每个存储过程启动的事务(即内部事务)中。

没有被选为死锁牺牲品的 session A 的 @@trancount 为 1,正如我们所料(我们没有结束外部事务)。但是受害者 session B 的 @@trancount 为 0。

为什么发生死锁时,内部事务和外部事务都结束了?有没有办法确保在死锁的情况下只结束内部事务?

似乎死锁错误的行为就像 XACT_ABORT 设置为 on(在这种情况下不是),因为不会执行导致死锁的调用之后的任何进一步查询语句.

这个问题的原因是如果发生死锁,是否知道是否可以再次运行查询。如果它发生在一个较大的事务中,即打算在其中调用多个查询,那么销毁该外部事务将意味着重新运行因死锁而受害的查询将安全.但是,如果它只停止其周围的环境,那么它会是安全的。

最佳答案

SQL Server 没有真正的嵌套事务。 SAVE TRANSACTION 和保存点名称等功能可能会强制像嵌套事务一样工作,但不是真的1

因此 ROLLBACK 的行为(不尝试使用保存点)总是会影响所有事务,无论嵌套级别如何。

并且由死锁破坏者强制回滚永远没有机会指定保存​​点名称。


1值得注意的是,每个人都必须“参与其中”。您不能将现有代码编写为使用 BEGIN/ROLLBACK 并将其嵌套在事务中。它必须重写为 SAVE TRANSACTION name/ROLLBACK name 现在它依赖于调用代码始终将其包装在现有事务中

关于sql - 为什么 SQL Server 死锁受害者错误 (1205) 会结束其所有事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51727556/

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