У меня есть приложение, подключенное к базе данных SQL Server 2014, которая объединяет несколько строк в один. Других подключений к этой базе данных пока приложение работает.Предотвращение взаимоблокировок в SQL Server
Сначала выберите фрагмент строк в течение определенного промежутка времени. Этот запрос использует некластеризованный поиск (столбец TIME), объединенный с кластеризованным поиском.
select ...
from FOO
where TIME >= @from and TIME < @to and ...
Затем мы обрабатываем эти строки в C# и записать изменения в качестве одного обновления и нескольких удалений, это происходит много раз в кусок. Они также используют некластеризованные запросы индекса.
begin tran
update FOO set ...
where NON_CLUSTERED_ID = @id
delete FOO where NON_CLUSTERED_ID in (@id1, @id2, @id3, ...)
commit
Я получаю блокировки при работе с несколькими параллельными кусками. Я пробовал использовать ROWLOCK
для update
и delete
, но по какой-то причине это вызвало еще больше тупиков, чем раньше, хотя между кусками нет перекрытий.
Тогда я пробовал TABLOCKX, HOLDLOCK
на update
, но это означает, что я не могу выполнить мой select
параллельно, поэтому я теряю преимущества параллелизма.
Любая идея, как я могу избежать взаимоблокировок, но все же обрабатывать несколько параллельных кусков?
Было бы безопасно использовать NOLOCK
на моем select
в этом случае, если не существует перекрытия строк между кусками? Тогда TABLOCKX, HOLDLOCK
будет блокировать только update
и delete
, правильно?
Или я должен просто согласиться с тем, что будут выполняться блокировки и повторить запрос в моем приложении?
UPDATE (дополнительная информация): Все тупики до сих пор не произошло в фазе update
и delete
, ни в select
. Я постараюсь сделать некоторые блокировки журналов, если я не смогу решить эту проблему сегодня (правильные флаги трассировки ранее не были включены).
UPDATE: Эти два устройство из тупиков, которые происходят с ROWLOCK
, оба они относятся только к delete
заявления и некластерному индексу она использует. Я не уверен, что они такие же, как тупики, которые происходят без каких-либо табличных подсказок, поскольку я не смог воспроизвести их.
Спросите, есть ли что-нибудь еще нужно от .xdl, я немного устал присоединять все это.
Вы пытались претендовать на 'UPDLOCK' во время вашего выбора? Таким образом, блокировка уже существует, когда вы обновляете/удаляете, что должно удержать вас от блокировки. Если возможно, поделитесь с нами некоторыми деталями регистрации тупиков. – Jens
Можете ли вы переместить всю обработку в хранимую процедуру? Вы также можете решить эту проблему, просто включив выделение снимков, но это действительно зависит от того, что вы делаете. –
@Jens К сожалению, сейчас я не могу получить блокировку. Кажется, что все потоки, которые потерпели неудачу из-за взаимоблокировок, были в фазе 'update' и' delete', поэтому изменение блокировки 'select' вряд ли повлияет на этот случай. К сожалению, у меня нет журналов в тупике, я посмотрю, могу ли я включить флаги следов тупика для следующей попытки. @ Nick.McDermaid Невозможно использовать изоляцию моментальных снимков, к сожалению. –