Это скорее пример, где TABLOCK не работал для меня, а TABLOCKX работал.
У меня есть 2 сеанса, оба используют уровень изоляции READ COMMITTED по умолчанию:
Сессия 1 - это явная транзакция, которая копирует данные со связанного сервера в набор таблиц в базе данных, и ее запуск занимает несколько секунд. [Пример, это удаляет Вопросы]
Сессия 2 - это оператор вставки, который просто вставляет строки в таблицу, в которую Сессия 1 не вносит изменений. [Например, он вставляет ответы].
(На практике несколько сеансов одновременно вставляют несколько записей в таблицу, пока сеанс 1 выполняет свою транзакцию).
Сессия 1 должна запросить таблицу, в которую вставляет Сессия 2, потому что она не может удалить записи, которые зависят от записей, которые были добавлены Сессией 2. [Пример: Удалить вопросы, на которые не было ответа].
Итак, пока сеанс 1 выполняется, а сеанс 2 пытается вставить, сеанс 2 каждый раз теряется в тупике.
Итак, оператор удаления в сеансе 1 может выглядеть примерно так:
УДАЛИТЬ TBLA ИЗ TBLQ ЛЕВЫЙ РЕЙТИНГ TBLX на ...
СЛЕВА ПРИСОЕДИНЯЙТЕСЬ К tblA ON ON tblQ.Qid = tblA.Qid
ГДЕ ... a.QId НУЛЬ и ...
Кажется, что тупик вызван конфликтом между запросами tblA, когда Сессия 2, [3, 4, 5, ..., n] пытается вставить в tblA.
В моем случае я мог бы изменить уровень изоляции транзакции сеанса 1 на SERIALIZABLE. Когда я сделал это: Менеджер транзакций отключил поддержку удаленных / сетевых транзакций.
Итак, я мог бы следовать инструкциям в принятом ответе, чтобы обойти его: Менеджер транзакций отключил поддержку удаленных / сетевых транзакций
Но а) меня не устраивало изменение уровня изоляции на SERIALIZABLE, в первую очередь - предположительно, это ухудшает производительность и может иметь другие последствия, которые я не учел, б) не понимал, почему это внезапно вызвало в транзакции возникла проблема при работе на связанных серверах, и c) не знаю, какие возможные дыры я мог бы открыть, разрешив доступ к сети.
Казалось, что в очень большой транзакции было только 6 запросов, которые вызывают проблемы.
Итак, я читал о TABLOCK и TabLOCKX.
Я не был кристально ясен в различиях, и не знал, сработает ли один из них. Но казалось, что так и будет. Сначала я попробовал TABLOCK, и это, похоже, не имело никакого значения. Конкурирующие сессии вызывали одинаковые тупики. Затем я попробовал TABLOCKX, и больше никаких тупиков.
Итак, в шести местах все, что мне нужно было сделать, это добавить WITH (TABLOCKX).
Итак, оператор удаления в сеансе 1 может выглядеть примерно так:
УДАЛИТЬ ТАБЛИЦУ ОТ ТАБЛИЦЫ q ВЛЕВО СОЕДИНЯТЬ ТАБЛИЦЫ x на ...
СЛЕДУЕТ ПРИСОЕДИНИТЬСЯ К tblA a С (TABLOCKX) ON tblQ.Qid = tblA.Qid
ГДЕ ... a.QId НУЛЬ и ...