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

Откуда:
Сообщений: 8
Добрый день. Пытаюсь разобраться с причиной дедлока. Суть примерно следующая в одной транзации выполняется чтение из таблицы () В другой транзакции выполняется многократное удаление строк, скорее всего там блокируются строки сначала "U", а потом повышаются до "Х". Вот как раз в момент когда 1-ая транзакция ожидает установки блокировки, а вторая уже наложила часть блокировок и пытается повысить очередную возникает deadlock. Вопрос собственно почему дедлок, если вторая транзакция началась раньше и уже установила блокировки "Х" на некоторые записи (и соответственно IX на страницы), то первая должна ожидать завершения второй чтобы наложить блокировку "S"? Или может быть так, что они одновременно наложили блокировки на разные страницы таблицы и теперь ждут друг друга. Возможно ли такое?
Граф.
+
Граф
<deadlock-list>
 <deadlock victim="process867288">
  <process-list>
   <process id="process867288" taskpriority="0" logused="0" waitresource="PAGE: 7:1:40755968" waittime="390" ownerId="65324080" transactionname="user_transaction" lasttranstarted="2013-03-29T20:02:42.090" XDES="0xc69a7950" lockMode="S" schedulerid="7" kpid="6804" status="suspended" spid="90" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2013-03-29T20:02:42.097" lastbatchcompleted="2013-03-29T20:02:42.093" clientapp="1CV82 Server" hostname="DC-1C03-CUBE" hostpid="4564" loginname="sa" isolationlevel="read committed (2)" xactid="65324080" currentdb="7" lockTimeout="60000" clientoption1="671228192" clientoption2="128056">
    <executionStack>
     <frame procname="adhoc" line="1" stmtstart="226" sqlhandle="0x020000000c97fe165e16a01e77d5aa425db49aeb6e35b005">
INSERT INTO #tt34 (_Q_000_F_000RRef, _Q_000_F_001) SELECT DISTINCT TOP 1000
T2._IDRRef,
T2._Date_Time
FROM _Reference5835 T1
INNER JOIN _Document2785 T2
ON (T1._Fld5838_TYPE = @P1 AND T1._Fld5838_RTRef = @P2 AND T1._Fld5838_RRRef = T2._IDRRef)
WHERE (@P3 = @P3) AND (T2._Date_Time &lt;= @P4) AND T2._Posted = @P5 AND (((T2._IDRRef &gt; @P6) AND (T2._Date_Time = @P7)) OR (T2._Date_Time &gt; @P7)) AND (T1._Fld6309 = @P3)
ORDER BY 2, 1     </frame>
     <frame procname="mssqlsystemresource.sys.sp_executesql" line="1" sqlhandle="0x0400ff7fbe80662601000000000000000000000000000000">
sp_executesql     </frame>
     <frame procname="adhoc" line="1" sqlhandle="0x01000700c8d2a13530f26d530c0000000000000000000000">
exec sp_executesql N&apos;INSERT INTO #tt34 (_Q_000_F_000RRef, _Q_000_F_001) SELECT DISTINCT TOP 1000
T2._IDRRef,
T2._Date_Time
FROM _Reference5835 T1
INNER JOIN _Document2785 T2
ON (T1._Fld5838_TYPE = @P1 AND T1._Fld5838_RTRef = @P2 AND T1._Fld5838_RRRef = T2._IDRRef)
WHERE (@P3 = @P3) AND (T2._Date_Time &lt;= @P4) AND T2._Posted = @P5 AND (((T2._IDRRef &gt; @P6) AND (T2._Date_Time = @P7)) OR (T2._Date_Time &gt; @P7)) AND (T1._Fld6309 = @P3)
ORDER BY 2, 1&apos;, N&apos;@P1 varbinary(1),@P2 varbinary(4),@P3 numeric(1,0),@P4 datetime,@P5 varbinary(1),@P6 varbinary(16),@P7 datetime&apos;, 0x08, 0x00000AE1, 1, {ts &apos;4013-02-11 23:59:59&apos;}, 0x01, 0xAF27005056BF68E911E22D92BFC87348, {ts &apos;4012-11-14 00:00:00&apos;}     </frame>
    </executionStack>
    <inputbuf>
exec sp_executesql N&apos;INSERT INTO #tt34 (_Q_000_F_000RRef, _Q_000_F_001) SELECT DISTINCT TOP 1000
T2._IDRRef,
T2._Date_Time
FROM _Reference5835 T1
INNER JOIN _Document2785 T2
ON (T1._Fld5838_TYPE = @P1 AND T1._Fld5838_RTRef = @P2 AND T1._Fld5838_RRRef = T2._IDRRef)
WHERE (@P3 = @P3) AND (T2._Date_Time &lt;= @P4) AND T2._Posted = @P5 AND (((T2._IDRRef &gt; @P6) AND (T2._Date_Time = @P7)) OR (T2._Date_Time &gt; @P7)) AND (T1._Fld6309 = @P3)
ORDER BY 2, 1&apos;, N&apos;@P1 varbinary(1),@P2 varbinary(4),@P3 numeric(1,0),@P4 datetime,@P5 varbinary(1),@P6 varbinary(16),@P7 datetime&apos;, 0x08, 0x00000AE1, 1, {ts &apos;4013-02-11 23:59:59&apos;}, 0x01, 0xAF27005056BF68E911E22D92BFC87348, {ts &apos;4012-11-14 00:00:00&apos;}    </inputbuf>
   </process>
   <process id="process5cf048" taskpriority="0" logused="301840" waitresource="PAGE: 7:1:40755935" waittime="149" ownerId="65387936" transactionname="user_transaction" lasttranstarted="2013-03-29T20:02:44.983" XDES="0xbdcee780" lockMode="IX" schedulerid="3" kpid="8000" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2013-03-29T20:02:45.260" lastbatchcompleted="2013-03-29T20:02:45.260" clientapp="1CV82 Server" hostname="DC-1C03-CUBE" hostpid="4480" loginname="sa" isolationlevel="read committed (2)" xactid="65387936" currentdb="7" lockTimeout="60000" clientoption1="671228192" clientoption2="128056">
    <executionStack>
     <frame procname="adhoc" line="1" stmtstart="72" sqlhandle="0x0200000026994702874a5194080e5823599937dcde34d985">
DELETE FROM T1
FROM _Reference5835 T1
WHERE T1._IDRRef = @P1 AND T1._Version = @P2     </frame>
     <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown     </frame>
    </executionStack>
    <inputbuf>
(@P1 varbinary(16),@P2 varbinary(8))DELETE FROM T1
FROM _Reference5835 T1
WHERE T1._IDRRef = @P1 AND T1._Version = @P2    </inputbuf>
   </process>
  </process-list>
  <resource-list>
   <pagelock fileid="1" pageid="40755968" dbid="7" objectname="cub.dbo._Reference5835" id="locka4a6b8400" mode="IX" associatedObjectId="72057607435976704">
    <owner-list>
     <owner id="process5cf048" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process867288" mode="S" requestType="wait"/>
    </waiter-list>
   </pagelock>
   <pagelock fileid="1" pageid="40755935" dbid="7" objectname="cub.dbo._Reference5835" id="lockafed0d780" mode="SIU" associatedObjectId="72057607435976704">
    <owner-list>
     <owner id="process867288" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="process5cf048" mode="IX" requestType="convert"/>
    </waiter-list>
   </pagelock>
  </resource-list>
 </deadlock>
</deadlock-list>



В планах запроса

SELECT:
Clustered Index Scan(OBJECT:([cub].[dbo].[_Reference5835].[PK___Referen__AC8ED0C47ED643E7] AS [T1]), WHERE:([cub].[dbo].[_Reference5835].[_Fld5838_TYPE] as [T1].[_Fld5838_TYPE]=[@P1] AND [cub].[dbo].[_Reference5835].[_Fld5838_RTRef] as [T1].[_Fld5838_RTRef]=[@P2] AND [cub].[dbo].[_Reference5835].[_Fld6309] as [T1].[_Fld6309]=[@P3]))

DELETE:

Clustered Index Seek(OBJECT:([cub].[dbo].[_Reference5835].[PK___Referen__AC8ED0C47ED643E7] AS [T1]), SEEK:([T1].[_IDRRef]=[@P1]) ORDERED FORWARD)

К сообщению приложен файл (select.txt - 9Kb) cкачать
6 апр 13, 00:28    [14143329]     Ответить | Цитировать Сообщить модератору
 Re: Помогите понять причину дедлока.  [new]
aleks2
Guest
1. По умолчанию сервер накладывает блокировки "по мере необходимости", а вовсе не "сразу". Т.е. по мере чтения/обработки записей.
2. Если порядок чтения записей различается, select может наложить S-блокировку на некую запись A и ждать освобождения записи B блокированной update. А update может наложить X-блокировку на запись В и ждать освобождения записи А, блокированной select.
3. У вас всего два выхода: а) обеспечить одинаковый порядок чтения строк таблицы - это очень сложно сделать; б) требовать для update сразу xlock, в пределе tablock, xlock.
6 апр 13, 09:40    [14144003]     Ответить | Цитировать Сообщить модератору
 Re: Помогите понять причину дедлока.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Я бы начал с rowlock для читающего запроса. Именно он лочит страницами и не дает спокойно конвертить интент-блокировки.
Кстати, когда сервер накладывает паглоки при выборке, он не отпускает предыдущую страницу, пока не наложит на следующую. Отсюда веселые дедлоки даже при read committed.

Сообщение было отредактировано: 6 апр 13, 12:53
6 апр 13, 12:50    [14144307]     Ответить | Цитировать Сообщить модератору
 Re: Помогите понять причину дедлока.  [new]
abe
Member

Откуда:
Сообщений: 8
Спасибо, теперь вроде прояснилось.
Есть еще вопрос, правда немного по другой теме.
Предположим есть три транзации:
Транзакция №1 накладывает эксклюзивную блокировку на некую запись, транзакция №2 пытается наложить блокировку на всю таблицу и ждет т.к. не может этого сделать, а транзакция № 3, которая началась позже, чем №2 хочет наложить блокировку на некую запись, которая не блокируется транзакцией 1, но будет заблокирована транзакцией №2. В каком порядке они будут выполнены? Сначала №2, а потом №3, или наоборот?
8 апр 13, 10:42    [14149916]     Ответить | Цитировать Сообщить модератору
 Re: Помогите понять причину дедлока.  [new]
Гость333
Member

Откуда:
Сообщений: 3683
abe
В каком порядке они будут выполнены? Сначала №2, а потом №3, или наоборот?

А эксперимент провести не хотите? Тогда всё надёжнее отложится в памяти, чем при ответе на форуме.
8 апр 13, 10:59    [14150012]     Ответить | Цитировать Сообщить модератору
 Re: Помогите понять причину дедлока.  [new]
abe
Member

Откуда:
Сообщений: 8
Эксперимент проведу, но может есть какие то ньюансы... не подскажете где можно об этом почитать???
8 апр 13, 12:02    [14150408]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить