Bra*_*rad 5 sql-server spring deadlock transactions jdbc
我有一个java应用程序,它在数据库上执行多个并发CRUD操作.我正在添加对SQLServer的支持,但在并发删除期间遇到死锁问题.经过一些调查后,似乎问题可能是由于特定桌子上的锁升级造成的.
为了解决这个问题,我决定使用UPDLOCK提示对所讨论的表进行所有读取"for update",以便可以避免死锁.但是,我仍然看到了这个问题.我在SQLServer中启用了跟踪,并在SQLServer日志中找到了以下死锁跟踪:
遇到死锁....打印死锁信息等待图
节点:1 KEY:5:72057594042384384(54048e7b3828)CleanCnt:3模式:X标志:0x0授权列表1:所有者:0x03D08C40模式:X Flg:0x0参考:0生命:02000000 SPID:62 ECID:0 XactLockInfo:0x04834274 SPID: 62 ECID:0语句类型:DELETE行#:1输入Buf:语言事件:(@ P0 nvarchar(4000))从part_data中删除part_id = @ P0请求者:ResType:LockOwner Stype:'OR'Xdes:0x04B511C8模式: U SPID:60 BatchID:0 ECID:0 TaskProxy:(0x058BE378)值:0x3d08500成本:(0/1296)
节点:2
KEY:5:72057594042384384(f903d6d6e0ac)CleanCnt:2模式:X标志:0x0授权列表0:所有者:0x03D088A0模式:X Flg:0x0参考:0生命:02000000 SPID:60 ECID:0 XactLockInfo:0x04B511EC SPID:60 ECID: 0语句类型:DELETE行#:1输入Buf:语言事件:(@ P0 nvarchar(4000))从part_data中删除part_id = @ P0请求者:ResType:LockOwner Stype:'OR'Xdes:0x04834250模式:U SPID: 62 BatchID:0 ECID:0 TaskProxy:(0x047BA378)值:0x3d089e0成本:(0/4588)
受害者资源所有者:ResType:LockOwner Stype:'OR'Xdes:0x04B511C8模式:U SPID:60 BatchID:0 ECID:0 TaskProxy:(0x058BE378)值:0x3d08500成本:(0/1296)
SQLServer探查器将此显示为两个持有更新(U)锁并尝试升级到独占(X)锁的客户端.我读过的SQLServer文档说在给定时间只有一个客户端可以在表上有一个(U)锁,所以我想知道为什么我看到跟踪中显示的情况.
该跟踪中引用的数据库对象是外键的索引.如果有经验解决这类问题的人可以提供建议,那将是一个很大的帮助.
谢谢,布拉德.
编辑按要求添加了死锁图xml:
<deadlock-list>
<deadlock victim="process989018">
<process-list>
<process id="process6aa7a8" taskpriority="0" logused="4844" waitresource="KEY: 5:72057594042384384 (5504bdfb7529)" waittime="9859" ownerId="613553" transactionname="implicit_transaction" lasttranstarted="2009-05-08T11:52:39.137" XDES="0x5fcbc30" lockMode="U" schedulerid="1" kpid="3516" status="suspended" spid="59" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2009-05-08T11:52:39.183" lastbatchcompleted="2009-05-08T11:52:39.183" clientapp="jTDS" hostname="LOIRE" hostpid="123" loginname="sa" isolationlevel="read committed (2)" xactid="613553" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" sqlhandle="0x0200000007c76c39efdd8317c6fa7b611b4fd958f05cfcf4">
delete from part_data where part_id = @P0 </frame>
</executionStack>
<inputbuf>(@P0 nvarchar(4000))delete from part_data where part_id = @P0</inputbuf>
</process>
<process id="process989018" taskpriority="0" logused="1528" waitresource="KEY: 5:72057594042384384 (5e0405cb0377)" waittime="1250" ownerId="613558" transactionname="implicit_transaction" lasttranstarted="2009-05-08T11:52:39.183" XDES="0x48318f0" lockMode="U" schedulerid="2" kpid="2692" status="suspended" spid="60" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2009-05-08T11:52:39.183" lastbatchcompleted="2009-05-08T11:52:39.183" clientapp="jTDS" hostname="LOIRE" hostpid="123" loginname="sa" isolationlevel="read committed (2)" xactid="613558" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" sqlhandle="0x0200000007c76c39efdd8317c6fa7b611b4fd958f05cfcf4">
delete from part_data where part_id = @P0 </frame>
</executionStack>
<inputbuf>(@P0 nvarchar(4000))delete from part_data where part_id = @P0</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594042384384" dbid="5" objectname="MESSAGESTOREDB61.dbo.part_data" indexname="idx_part_data_part_id" id="lock3cab740" mode="X" associatedObjectId="72057594042384384">
<owner-list>
<owner id="process6aa7a8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process989018" mode="U" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594042384384" dbid="5" objectname="MESSAGESTOREDB61.dbo.part_data" indexname="idx_part_data_part_id" id="lock3cad340" mode="X" associatedObjectId="72057594042384384">
<owner-list>
<owner id="process989018" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process6aa7a8" mode="U" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
Run Code Online (Sandbox Code Playgroud)
我假设您运行了类似的命令:DBCC TRACEON(1222,-1)”和/或“DBCC TRACEON(1204,-1)”。我发现 SQLServer 日志中的死锁跟踪很难阅读。您确定这是尝试升级到排它(X)锁吗?
尝试在探查器中运行运行跟踪(选择空白模板),选择“死锁图事件”,然后在出现的新选项卡(事件提取设置)上,将每个事件保存(选中“单独保存死锁 XML 事件”)它自己的文件。在 xml 查看器中打开此文件,很容易看出发生了什么。每个进程都包含一个过程/触发器/等调用的执行堆栈,所有的锁也都在那里。我发现很难相信 col=@value 的两个 DELETE 导致了问题,查看执行堆栈,是否有触发器或其他情况发生?
查看文件的“资源列表”部分,它将显示导致死锁的每个进程正在锁定和持有的内容。弄清楚如何不锁定其中之一,死锁就会得到解决。
| 归档时间: |
|
| 查看次数: |
6981 次 |
| 最近记录: |