Почему возникает взаимоблокировка?

Я использую небольшую транзакцию, которая состоит из двух простых запросов: select и update:

SELECT * FROM XYZ WHERE ABC = DEF

и

UPDATE XYZ SET ABC = 123
WHERE ABC = DEF

Нередко бывает ситуация, когда транзакция запускается два потока, и в зависимости от уровня изоляции возникает взаимоблокировка (RepeatableRead, Serialization). Обе транзакции пытаются прочитать и обновить одну и ту же строку. Мне интересно, почему это происходит. Какой порядок запросов приводит к тупиковой ситуации? Я немного читал о блокировках (совместно используемых, эксклюзивных) и о том, как долго блокировки для каждого уровня изоляции, но я все еще не совсем понимаю ...

Я даже подготовил простой тест, который всегда приводит к тупиковой ситуации . Я посмотрел результаты теста в SSMS и SQL Server Profiler. Я начал первый запрос, а затем сразу второй.

Первый запрос:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT ...
WAITFOR DELAY '00:00:04'
UPDATE ...
COMMIT

Второй запрос:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT ...
UPDATE ...
COMMIT

Сейчас я не могу показать вам подробные журналы, но это выглядит примерно так (я очень вероятно, пропущен. Блокировка: тупик и т.д. где-то):

(1) SQL:BatchStarting: First query
(2) SQL:BatchStarting: Second query
(3) Lock:timeout for second query
(4) Lock:timeout for first query
(5) Deadlock graph

Если я хорошо понимаю блокировки, в (1) первый запрос принимает общую блокировку (для выполнения SELECT), затем переходит в спящий режим и сохраняет общую блокировку до конца транзакции. В (2) второй запрос также принимает разделяемую блокировку (SELECT), но не может принимать исключительную блокировку (UPDATE), пока есть общие блокировки в той же строке, что приводит к Lock: timeout. Но я не могу объяснить, почему возникает таймаут для второго запроса. Наверное, я плохо понимаю весь процесс. Кто-нибудь может дать хорошее объяснение?

Я не заметил тупиковых ситуаций при использовании ReadCommitted, но боюсь, что они могут возникнуть. Какое решение вы порекомендуете?

6
задан Grzes 8 August 2011 в 19:45
поделиться