При выполнении оператора SELECT с объединением двух таблиц SQL Server кажется
заблокируйте обе таблицы заявления по отдельности. Например, по запросу типа
это:
SELECT ...
FROM
table1
LEFT JOIN table2
ON table1.id = table2.id
WHERE ...
Я узнал, что порядок замков зависит от условия ГДЕ.
оптимизатор запросов пытается создать план выполнения, который читает только столько
строки по мере необходимости. Так что если условие WHERE содержит столбец table1
сначала он получит строки результата из таблицы table1, а затем получит соответствующий
строки из таблицы2. Если столбец из таблицы 2, он будет делать это по-другому
круглый. Более сложные условия или использование индексов могут влиять на
решение оптимизатора запросов тоже.
Когда данные, считанные оператором, должны быть обновлены позже в транзакции
с инструкциями UPDATE не гарантируется, что порядок UPDATE
операторы соответствуют порядку, который использовался для чтения данных из 2 таблиц.
Если другая транзакция пытается прочитать данные, когда транзакция обновляет
таблиц это может вызвать тупик, когда оператор SELECT выполняется в
между операторами UPDATE, потому что ни SELECT не может получить блокировку на
Первая таблица также не может ОБНОВИТЬ блокировку второй таблицы. За
Пример:
T1: SELECT ... FROM ... JOIN ...
T1: UPDATE table1 SET ... WHERE id = ?
T2: SELECT ... FROM ... JOIN ... (locks table2, then blocked by lock on table1)
T1: UPDATE table2 SET ... WHERE id = ?
Обе таблицы представляют иерархию типов и всегда загружаются вместе. Так что
имеет смысл загрузить объект, используя SELECT с JOIN. Загрузка обеих таблиц
индивидуально не даст оптимизатору запросов шанс найти лучшее
план выполнения. Но поскольку операторы UPDATE могут обновлять только одну таблицу за
время, которое это может вызвать взаимоблокировки, когда объект загружается в то время как объект
обновляется другой транзакцией. Обновления объектов часто вызывают ОБНОВЛЕНИЯ на
обе таблицы, когда свойства объекта, которые принадлежат к разным типам
иерархия типов обновлена.
Я пытался добавить подсказки блокировки в инструкцию SELECT, но это не
изменить проблему. Это просто вызывает тупик в операторах SELECT, когда
оба оператора пытаются заблокировать таблицы, и один оператор SELECT получает блокировку
в обратном порядке другого утверждения. Может быть, это будет возможно
загружать данные для обновлений всегда с одним и тем же оператором, заставляя блокировки быть
в том же порядке. Это предотвратит тупик между двумя транзакциями, которые
хочу обновить данные, но не помешает транзакции, которая только читает
данные для взаимоблокировки, которые должны иметь различные условия ГДЕ.
Единственный обходной путь, так что до сих пор кажется, что чтение не может получить блокировки
совсем. В SQL Server 2005 это можно сделать с помощью SNAPSHOT ISOLATION.
единственным способом для SQL Server 2000 было бы использование изоляции READ UNCOMMITED
уровень.
Я хотел бы знать, есть ли другая возможность предотвратить SQL Server
от возникновения этих тупиков?