Если я вас правильно слышу, вы говорите о вставке, которая блокирует себя, а не о двух отдельных запросах, блокирующих друг друга.
У нас была похожая проблема: пакет служб SSIS пытался вставить группу данных в таблицу, но пытался убедиться, что эти строки еще не существуют. Существующий код был что-то вроде (значительно упрощено):
INSERT INTO bigtable
SELECT customerid, productid, ...
FROM rawtable
WHERE NOT EXISTS (SELECT CustomerID, ProductID From bigtable)
AND ... (other conditions)
Это закончилось тем, что блокировало себя, потому что выбор в WHERE NOT EXISTS препятствовал выполнению INSERT.
Мы рассмотрели несколько различных вариантов, и я позволю вам решить, какой подход вам подходит:
- Изменение уровня изоляции транзакции (см. в этой статье MSDN ). Наш пакет служб SSIS по умолчанию был SERIALIZABLE, что является наиболее ограничительным. (обратите внимание, что перед тем, как выбрать этот параметр, будьте в курсе проблем с READ UNCOMMITTED или NOLOCK)
- Создать УНИКАЛЬНЫЙ индекс с IGNORE_DUP_KEY = ON . Это означает, что мы можем вставить ВСЕ строки (и полностью удалить предложение «ГДЕ НЕ ВХОДИТ»). Дубликаты будут отклонены, но пакет не завершится с ошибкой, и все остальные допустимые строки все равно будут вставлены.
- Измените логику запроса , чтобы сделать что-то вроде помещения всех строк-кандидатов во временную таблицу, затем удаления всех строк, которые уже находятся в месте назначения, и вставки остальных.
В нашем случае у нас уже были данные во временной таблице, поэтому мы просто удалили строки, которые не хотели вставлять, и выполнили простую вставку для остальных.