【问题标题】:Deadlock: property mode in keylock resource-list differs from owner-list mode死锁:keylock 资源列表中的属性模式与所有者列表模式不同
【发布时间】:2012-01-16 13:22:43
【问题描述】:

我最近一直在处理我们的应用程序中的一些死锁情况,并且有一个对我来说似乎很奇怪的新案例。错误日志显示了这一点(没有执行堆栈,我相信此时无关紧要):

deadlock-list
  deadlock victim=process84db88
   process-list
    process id=process84db88 taskpriority=0 logused=0 waitresource=KEY: 11:72057594409844736 (8194443284a0) waittime=4685 ownerId=3632385974 transactionname=SELECT lasttranstarted=2011-12-07T16:21:16.287 XDES=0x32f68fca0 lockMode=S schedulerid=6 kpid=6392 status=suspended spid=93 sbid=0 ecid=0 priority=0 trancount=0 lastbatchstarted=2011-12-07T16:21:16.287 lastbatchcompleted=2011-12-07T16:21:16.287 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=4156 loginname=XXX isolationlevel=read committed (2) xactid=3632385974 currentdb=11 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
     executionStack
      ........   
    process id=process47bdc8 taskpriority=0 logused=240604 waitresource=KEY: 11:72057594409844736 (829df5d1e88e) waittime=4681 ownerId=3632397262 transactionname=UPDATE lasttranstarted=2011-12-07T16:21:26.100 XDES=0x2f00b93c0 lockMode=X schedulerid=1 kpid=6568 status=suspended spid=88 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2011-12-07T16:21:25.640 lastbatchcompleted=2011-12-07T16:21:25.640 clientapp=.Net SqlClient Data Provider hostname=DE-1809 hostpid=4156 loginname=XXX isolationlevel=read committed (2) xactid=3632397262 currentdb=11 lockTimeout=4294967295 clientoption1=673316896 clientoption2=128056
     executionStack
      .........  
   resource-list
    keylock hobtid=72057594409844736 dbid=11 objectname=dbo.OurTable indexname=PK_OurTable id=lock1d9aa0b00 mode=X associatedObjectId=72057594409844736
     owner-list
      owner id=process47bdc8 mode=X
     waiter-list
      waiter id=process84db88 mode=S requestType=wait
    keylock hobtid=72057594409844736 dbid=11 objectname=dbo.OurTable indexname=PK_OurTable id=lock1a56cb580 mode=U associatedObjectId=72057594409844736
     owner-list
      owner id=process84db88 mode=S
     waiter-list
      waiter id=process47bdc8 mode=X requestType=convert

锁定发生在我们其中一张表的同一个聚集索引中的一个键上。让我有点困惑的是资源列表中最后一个键锁行中的模式。

它说:mode=U,而相应所有者列表中的所有者说:mode=S

我应该如何阅读这篇文章?这两种模式通常是相同的。这些模式有何不同?

【问题讨论】:

    标签: sql-server sql-server-2008 tsql deadlock error-log


    【解决方案1】:

    MSDN 的这句话可能提供了一个解释:

    为避免这种潜在的死锁问题,使用了更新 (U) 锁。 只有一个事务可以在某个时间获得对资源的更新 (U) 锁 时间。如果一个事务修改了一个资源,更新(U)锁是 转换为独占 (X) 锁。否则,锁被转换 共享模式锁。

    所以一个请求共享锁的事务(可能是第一个)最终会持有更新锁。如果事务想要进行更新,更新锁只是为事务提供了转换为排他锁的选项。

    如果两个事务读取然后写入同一行,则此机制会有所帮助。在您的情况下,有两行在起作用。第一个事务在 A 行上有一个排他锁,正在等待转换为 B 行上的排他锁。第二个事务在 B 行上有一个共享锁,这实际上是一个更新锁,它正在等待行上的排他锁A.

    【讨论】:

      【解决方案2】:

      我认为这意味着process47bdc8 在该资源上有一个U 锁,并且正在等待将其转换为X 锁但不能因为process84db88 已经有一个S 锁它。

      S 锁定和U 锁定are compatible

      【讨论】:

      • 你可能是对的马丁。进程 process84db88 只选择一些数据,不在事务中运行,而 OurTable 在该查询中作为连接。既然是同一个索引上的锁,你知道SQL Server是如何获取它的锁的吗?它可以从选择查询中获得一个锁,但在同一查询请求的第二个锁上失败吗?不应该获得所有锁或没有。对我来说,它似乎是这样工作的:请求锁定 1,请求被授予向前一步并请求锁定 2,请求被拒绝你必须等待锁定 2,但仍然坚持锁定 1。这不可能吧?
      • @John - 在readcommitted 是的,它将在读取数据时单独取出行S 锁,并在读取数据后立即释放它们。您可以使用 SQL Server Profiler 跟踪获取和释放锁的事件以查看这一点(在开发服务器上,因为此跟踪可以生成大量数据)
      • @John - BTW:如果您在 Profiler 中进行跟踪,您可能会看到行 S 锁并不总是被取出。 The explanation for that behavior is in this article
      • 发生死锁是因为两个进程相互等待一段时间,对吧?因此,如果 process1 获得了 key1 上的锁,它应该在读取数据后释放该锁吗?然后,如果 process2 持有对 key2 的锁,并且 process1 请求对 key2 进行锁定,则 process2 可以等到 process1 读取 key1 上的数据并获得自己的锁,完成其更新/插入..whatever 并释放其所有锁,然后 process1 是有空继续阅读key2上的数据吗?我希望你能理解我在这里写的任何东西.. :)
      • @John - 你在问为什么死锁不能通过process84db88 解决,因为它已经读取了数据而仅仅释放它的 S 锁?实际上不确定。好问题!跟踪 Profiler 中的锁定事件应该可以对此有所了解。
      猜你喜欢
      • 2019-09-15
      • 2012-12-30
      • 2014-09-29
      • 2023-01-18
      • 2019-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多