我的应用程序的一部分在打开事务隔离级别上的连接后,按照业务逻辑更新表,然后进行可重复读取。在罕见的情况下,如果此操作与应用程序中打开不同连接并试图将同一记录重置为其默认值的另一部分相同。我得到跟随错误
Msg 1205, Level 13, State 45, Line 7
Transaction (Process ID 60) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.我想我可以用下面的例子重现这个问题。
1.
create table Accounts
(
id int identity(1,1),
Name varchar(50),
Amount decimal
)2.
insert into Accounts (Name,Amount) values ('ABC',5000)
insert into Accounts (Name,Amount) values ('WXY',4000)
insert into Accounts (Name,Amount) values ('XYZ',4500)3.
以可重复读取的方式启动具有隔离级别的长事务
Set transaction isolation level REPEATABLE READ
begin tran
declare @var int
select @var=amount
from Accounts
where id=1
waitfor delay '0:0:10'
if @var > 4000
update accounts
set amount = amount -100;
Commit4.
而上面的步骤3仍在执行中。在另一个连接上启动另一个事务
Begin tran
update accounts
set Amount = 5000
where id = 1
commit tran在步骤3中启动的事务将最终完成,但在步骤4中启动的事务将失败,出现以下错误消息。
Msg 1205, Level 13, State 45, Line 7
Transaction (Process ID 60) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.在第4步中,我有哪些选项可以最终运行事务,其思想是能够将记录重置为默认值,在这种情况下,对其他事务执行的任何操作都应该被覆盖。如果这两个事务不是并发的,我看不出有什么问题。
发布于 2013-09-01 11:15:35
其想法是能够将记录重置为默认值。
您希望按什么顺序应用更新?你想要“重置”总是通过吗?然后,在步骤3中的更新完成后,您需要严格执行重置。此外,重置更新应该使用更高的锁模式以避免死锁:
update accounts WITH (XLOCK)
set Amount = 5000
where id = 1这样,重置将等待另一个事务先完成,因为另一个tran有一个S锁。
或者,步骤3获得一个U锁或X锁.
发布于 2013-09-01 11:10:44
可以将setp 4中事务的死锁优先级设置为更高,以获得更多详细信息(请参见http://technet.microsoft.com/en-us/library/ms186736.aspx )。
https://stackoverflow.com/questions/18557782
复制相似问题