Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 дедлок в простом апдейте  [new]
fduch f.f.
Member

Откуда: Белокаменная
Сообщений: 260
приложение в много потоков обновляет данные в таблице

из-за этого у меня дедлоки

если я правильно понимаю, причина дедлока - конверсия блокировок
думаю может как-то поставить хинты так что бы накладывалась сразу X блокировка вместо U

посоветуйте что лучше сделать?

граф дедлока ниже


автор
<event name="xml_deadlock_report" package="sqlserver" timestamp="2016-06-14T15:35:26.741Z">
<data name="xml_report">
<value>
<deadlock>
<victim-list>
<victimProcess id="process1ebcb7444" />
</victim-list>
<process-list>
<process id="process1ebcb7444" taskpriority="0" logused="400" waitresource="KEY: 4:72057594045661144 (b75cd2c40c1d)" waittime="55" ownerId="1342567747" transactionname="user_transaction" lasttranstarted="2016-06-14T11:35:26.027" XDES="0x2c4a4cb40" lockMode="U" schedulerid="3" kpid="9924" status="suspended" spid="60" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-06-14T11:35:26.693" lastbatchcompleted="2016-06-14T11:35:26.690" lastattention="1900-01-01T00:00:00.690" clientapp=".Net SqlClient Data Provider" hostname="N01" hostpid="14040" loginname="sa" isolationlevel="read committed (2)" xactid="1342567747" currentdb="4" lockTimeout="4294967295" clientoption1="671044672" clientoption2="124056">
<executionStack>
<frame procname="MainDB.dbo.SetItemStatus" line="6" stmtstart="232" stmtend="554" sqlhandle="0x030004005fca042736b3be0025a6000001000000000000000000000000000000000000000000000000000000">
update a
set IStatus = @istatus,
TimeUpdated = @timeUpdated
from ItemState a with (rowlock)
inner join @ids il on a.Id = il.I </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 4 Object Id = 654625375] </inputbuf>
</process>
<process id="process35a152ca4" taskpriority="0" logused="416" waitresource="KEY: 4:72057594045661144 (b43f7e94be45)" waittime="59" ownerId="1342567495" transactionname="user_transaction" lasttranstarted="2016-06-14T11:35:26.577" XDES="0x36c6e49f0" lockMode="U" schedulerid="3" kpid="4452" status="suspended" spid="59" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-06-14T11:35:26.593" lastbatchcompleted="2016-06-14T11:35:26.590" lastattention="1900-01-01T00:00:00.590" clientapp=".Net SqlClient Data Provider" hostname="N01" hostpid="14040" loginname="sa" isolationlevel="read committed (2)" xactid="1342567495" currentdb="4" lockTimeout="4294967295" clientoption1="671044672" clientoption2="124056">
<executionStack>
<frame procname="MainDB.dbo.SetItemStatus" line="6" stmtstart="232" stmtend="554" sqlhandle="0x030004005fca042736b3be0025a6000001000000000000000000000000000000000000000000000000000000">
update a
set IStatus = @istatus,
TimeUpdated = @timeUpdated
from ItemState a with (rowlock)
inner join @ids il on a.Id = il.I </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 4 Object Id = 654625375] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594045661144" dbid="4" objectname="MainDB.dbo.ItemState" indexname="PK_ItemState" id="lock2faa5db40" mode="X" associatedObjectId="72057594045661144">
<owner-list>
<owner id="process35a152ca4" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process1ebcb7444" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594045661144" dbid="4" objectname="MainDB.dbo.ItemState" indexname="PK_ItemState" id="lock290c4f500" mode="X" associatedObjectId="72057594045661144">
<owner-list>
<owner id="process1ebcb7444" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process35a152ca4" mode="U" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</value>
</data>
</event>
15 июн 16, 12:20    [19295090]     Ответить | Цитировать Сообщить модератору
 Re: дедлок в простом апдейте  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
fduch f.f.
если я правильно понимаю, причина дедлока - конверсия блокировок
Нет.
Причина - @ids из разных соединений пересекаются по содержимому и данные в них не упорядочены по I.

fduch f.f.
посоветуйте что лучше сделать?
Обеспечить уникальность содержимого @ids в каждом соединении.
Если это невозможно, добавить в @ids кластерный индекс по I.
15 июн 16, 12:36    [19295183]     Ответить | Цитировать Сообщить модератору
 Re: дедлок в простом апдейте  [new]
fduch f.f.
Member

Откуда: Белокаменная
Сообщений: 260
invm,
спасибо, попробую сделать кластерный индекс

подскажите плиз, как правильно интерпретировать этот план?
- сначала процесс 444 наложил (X) блокировку на строку A
- потом процесс ca4 наложил (X) блокировку на строку B
- потом 444 хочет блокировку (U) на B
- потом ca4 хочет блокировку (U) на A
возникает дедлок

т.е. проблема в последовательности наложения блокировок
у процесса 444 -> A,B
у процесса ca4 -> B,A

если будет кластарный индекс то у обоих процессов будет одинаковая последовательность
15 июн 16, 16:14    [19296254]     Ответить | Цитировать Сообщить модератору
 Re: дедлок в простом апдейте  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
fduch f.f.
т.е. проблема в последовательности наложения блокировок
у процесса 444 -> A,B
у процесса ca4 -> B,A
Да.
fduch f.f.
если будет кластарный индекс то у обоих процессов будет одинаковая последовательность
Да. Но без гарантий.
15 июн 16, 16:25    [19296325]     Ответить | Цитировать Сообщить модератору
 Re: дедлок в простом апдейте  [new]
fduch f.f.
Member

Откуда: Белокаменная
Сообщений: 260
invm
fduch f.f.
если будет кластарный индекс то у обоих процессов будет одинаковая последовательность
Да. Но без гарантий.


сделал кластерный индекс, но дедлоки всеравно остались
пробовал перегружать из табличной переменной во временную таблицу с кластерным индексом, все равно не помогает
21 июн 16, 14:09    [19318848]     Ответить | Цитировать Сообщить модератору
 Re: дедлок в простом апдейте  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
fduch f.f.,

Вытащите из кеша план запроса
update a
set IStatus = @istatus,
TimeUpdated = @timeUpdated
from ItemState a with (rowlock)
inner join @ids il on a.Id = il.I 
и опубликуйте его в формате sqlplan.
21 июн 16, 15:42    [19319322]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить