У меня есть приложение Java, которое выполняет несколько одновременных операций CRUD в базе данных. Я добавляю поддержку SQLServer, но у меня возникают проблемы с блокировкой при одновременном удалении. После некоторого расследования выяснилось, что проблема может быть связана с эскалацией блокировки на конкретной таблице.SQLServer deadlock
В попытке исправить это я решил сделать все прочитанные на рассматриваемой таблице «обновления», используя подсказку UPDLOCK, чтобы можно было избежать взаимоблокировки. Тем не менее, я все еще вижу проблему. Я включил трассировку в SQLServer и обнаружили следующее тупиковый след в SQLServer журналах:
Тупик встречается .... Печать информации тупиковой Wait-для графа
Node: 1 KEY: 5: 72057594042384384 (54048e7b3828) CleanCnt: 3 Режим: X Флаги: 0x0 Список грантов 1: Владелец: 0x03D08C40 Режим: X Flg: 0x0 Ref: 0 Life: 02000000 SPID: 62 ECID: 0 XactLockInfo: 0x04834274 SPID: 62 ECID: 0 Statement Тип: DELETE Строка #: 1 Ввод Buf: Язык Событие: (@ P0 nvarchar (4000)) удалить из part_data, где part_id = @ P0 Запрошено: ResType: LockOwner Stype: 'OR'Xdes: 0x04B511C8 режим: U SPID: 60 BatchID: 0 ОЭСИ: 0 TaskProxy: (0x058BE378) Значение: 0x3d08500 Стоимость: (0/1296)
Узел: 2
KEY: 5: 72057594042384384 (f903d6d6e0ac) CleanCnt: 2 Режим: X Flags: 0x0 Grant Список 0: Владелец: 0x03D088A0 Режим: X Flg: 0x0 Ссылка: 0 Жизнь: 02000000 ИСП: 60 ОЭСИ: 0 XactLockInfo: 0x04B511EC ИСП: 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)
Victim ресурсов Владелец: ResType: LockOwner Stype: 'OR'Xdes: 0x04B511C8 режим: U SPID: 60 BatchID: 0 ОЭСИ: 0 TaskProxy: (0x058BE378) Значение : 0x3d08500 Стоимость: (0/1296)
Профилировщик SQLServer показывает это как два клиента, у которых есть блокировка обновлений (U), и пытается перейти на эксклюзивные (X) блокировки. В документах SQLServer, которые я прочитал, говорится, что только один клиент может иметь (U) блокировку таблицы в данный момент времени, поэтому мне интересно, почему я вижу ситуацию, показанную в трассировке.
Объект базы данных, на который ссылается эта трасса, является индексом внешнего ключа. Если кто-нибудь, у кого есть опыт в устранении такого рода проблем, может предложить советы, это будет большой помощью.
Thanks, Brad.
EDIT добавил тупиковый граф 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>
У вас есть каскад-удаление где-нибудь? –
Привет, Стефан. Нет, у меня нет ограничений каскадного удаления. – Brad
Формат веб-экрана не имеет значения, скопируйте/вставьте в локальный файл .XML и откройте его, и он будет выглядеть хорошо. –