Предотвращение блокировки всей таблицы во время массовой вставки - PullRequest
2 голосов
/ 30 сентября 2011

У меня есть хранимая процедура, которая выполняет массовую вставку в таблицу. Я добавил команду BEGIN TRANSACTION чуть выше запроса INSERT, чтобы включить ROLL BACK, если что-то пойдет не так. Когда началась массовая вставка, она заблокировала всю таблицу, и другие пользователи не смогли выполнить SELECT в той же таблице.

Я не понимаю, почему SQL Server блокирует всю таблицу даже на SELECT.

Я использую SQL Server 2005 Express. Это проблема с этой версией или она сохраняется и в 2008 году? Как преодолеть эту ситуацию? Авторы не должны блокировать читателей .

Ответы [ 3 ]

5 голосов
/ 01 октября 2011

Писатели не должны блокировать читателей

Это верно только для изоляции моментальных снимков , все остальные уровни изоляции требуют, чтобы и читатели блокировали записи, и писатели блокировали читатели (грязное чтение не учитывается, поскольку они несовместимы и должны никогда не будет использоваться). Если вам нужно такое поведение, тогда используйте управление версиями строк (ссылка содержит решение).

Почему массовая вставка блокирует всю таблицу?

Это на самом деле может быть или не быть правдой. Поведение находится под вашим контролем:

TABLOCK

Указывает, что блокировка на уровне таблицы приобретается на время операция массового импорта. Таблица может быть загружена одновременно несколько клиентов, если в таблице нет индексов и указан TABLOCK. По умолчанию поведение блокировки определяется параметром таблицы table lock on bulk load.

Подробнее см. В спецификации продукта: Управление поведением блокировки для массового импорта .

4 голосов
/ 30 сентября 2011

У вас есть открытая транзакция. Это означает, что SQL Server необходимо сохранить состояние таблицы, а любые изменения, которые вы вносите, являются "грязными" и незафиксированными.

Если вы SELECT из таблицы, которая в настоящее время изменяется с помощью открытой (явной) транзакции, SELECT будет ожидать, пока таблица не будет в стабильном состоянии, и транзакция будет либо зафиксирована, либо откатана.

Чтобы обойти это, вы можете изменить уровень изоляции транзакции в запросе SELECT.

0 голосов
/ 30 сентября 2011

Если вы указываете TABLOCK в вашем проце, не надо.

...