Deadlock: режим свойств в списке ресурсов блокировки ключа отличается от режима списка владельцев - PullRequest
2 голосов
/ 09 декабря 2011

Я недавно работал с некоторыми тупиковыми ситуациями в нашем приложении, и у меня есть новый случай, который кажется мне странным. Журнал ошибок отображает это (без стеков выполнения, которые не имеют значения в настоящее время, я полагаю):

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 .

Как мне это прочитать? Эти два режима обычно одинаковы. Чем эти режимы могут отличаться?

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

Я бы интерпретировал это как означающее, что process47bdc8 имеет блокировку U для этого ресурса и ожидает преобразования ее в блокировку X, но не может, поскольку process84db88 уже имеет блокировку S это.

S замки и U замки совместимы .

1 голос
/ 09 декабря 2011

Эта цитата из MSDN может содержать объяснение:

Чтобы избежать этой потенциальной проблемы взаимоблокировки, используются блокировки обновления (U). Только одна транзакция может получить блокировку обновления (U) для ресурса на время. Если транзакция изменяет ресурс, блокировка обновления (U) преобразован в эксклюзивный (X) замок. В противном случае замок преобразуется на блокировку общего режима.

Таким образом, одна транзакция (вероятно, первая), которая запрашивает общую блокировку, в итоге удерживает блокировку обновления. Блокировка обновления просто дает транзакции возможность преобразоваться в исключительную блокировку, если она хочет выполнить обновление.

Этот механизм помогает, если две транзакции читают, а затем записывают в одну и ту же строку. В вашем случае в игре два ряда. Первая транзакция имеет эксклюзивную блокировку в строке A и ожидает преобразования в монопольную блокировку в строке B. Вторая транзакция имеет общую блокировку в строке B, это действительно блокировка обновления, и она ожидает эксклюзивную блокировку в строке. A.

...