Итак,
SPID 58 делает
INSERT INTO table1(...) VALUES (...)
SET @ID = SCOPE_IDENTITY()
INSERT INTO table2(PARENT_ID, ...) VALUES (@ID, ...)
Все это в хранимой процедуре. Процедура выполняется с указанием явной транзакции
Code: Select all
SqlCommand cmd = new SqlCommand("dbo.ap_VehCommitWork_SE", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted);
cmd.Transaction = tran;
Далее, SPID 54 делает
SELECT ...
FROM table1
WHERE ID IN (SELECT PARENT_ID
FROM table2
WHERE (...)
GROUP BY ...
HAVING COUNT(...) = ...)
Транзакция - неявная. По умолчанию Isolation Level тоже Read Committed. Теперь собственно deadlock info (я заменил object_id на условное имя таблицы):
Deadlock encountered .... Printing deadlock information
2003-08-12 18:57:32.40 spid3
2003-08-12 18:57:32.40 spid3 Wait-for graph
2003-08-12 18:57:32.40 spid3
2003-08-12 18:57:32.40 spid3 Node:1
2003-08-12 18:57:32.40 spid3 KEY: 8:table1:1 (4200e3437b80) CleanCnt:1 Mode: X Flags: 0x0
2003-08-12 18:57:32.40 spid3 Grant List 0::
2003-08-12 18:57:32.40 spid3 Owner:0x4725e5c0 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:58 ECID:0
2003-08-12 18:57:32.40 spid3 SPID: 58 ECID: 0 Statement Type: INSERT Line #: 51
2003-08-12 18:57:32.40 spid3 Input Buf: RPC Event: dbo.ap_VehCommitWork_SE;1
2003-08-12 18:57:32.40 spid3 Requested By:
2003-08-12 18:57:32.40 spid3 ResType:LockOwner Stype:'OR' Mode: S SPID:54 ECID:0 Ec:(0x4336B568) Value:0x4725aec0 Cost:(0/0)
2003-08-12 18:57:32.40 spid3
2003-08-12 18:57:32.40 spid3 Node:2
2003-08-12 18:57:32.40 spid3 TAB: 8:table2 [] CleanCnt:1 Mode: S Flags: 0x0
2003-08-12 18:57:32.40 spid3 Grant List 0::
2003-08-12 18:57:32.40 spid3 Owner:0x46df6a60 Mode: S Flg:0x0 Ref:2 Life:00000001 SPID:54 ECID:0
2003-08-12 18:57:32.40 spid3 SPID: 54 ECID: 0 Statement Type: SELECT Line #: 1
2003-08-12 18:57:32.40 spid3 Input Buf: Language Event: SELECT ...
2003-08-12 18:57:32.40 spid3 Requested By:
2003-08-12 18:57:32.40 spid3 ResType:LockOwner Stype:'OR' Mode: IX SPID:58 ECID:0 Ec:(0x48681568) Value:0x4725ae80 Cost:(0/660)
2003-08-12 18:57:32.40 spid3 Victim Resource Owner:
2003-08-12 18:57:32.40 spid3 ResType:LockOwner Stype:'OR' Mode: S SPID:54 ECID:0 Ec:(0x4336B568) Value:0x4725aec0 Cost:(0/0)
Т.е.
1. SPID 58 вставил запись в table1, в то же время SPID 54 обрабатывает подзапрос на table2
2. SPID 58 готов вставить запись в table2, но ждет SPID 54
3. SPID 54 не может завершится, так как SPID 58 держит лок на table 1.
Имеем deadlock.
Как выход я вижу вынос подзапроса - с созданием #temp и join table1 и #temp.
Вопрос однако, почему SPID 58 INSERT получил KEY, а не RID ?
Если я правильно понял BOL:
Key-range locking solves the phantom read concurrency problem and supports serializable transactions. Key-range locks cover individual records and the ranges between records, preventing phantom insertions or deletions into a set of records accessed by a transaction. Key-range locks are used only on behalf of transactions operating at the serializable isolation level.
У меня isolation level не Serializable...