Предотвратить тупик в совершенном чтении SELECT - PullRequest
0 голосов
/ 18 февраля 2019

Я извлекаю данные из бизнес-системы, предоставленной третьей стороной, для использования в отчетности.Я использую один оператор SELECT, выданный из компонента источника задачи потока данных служб SSIS, который объединяет несколько таблиц в исходной системе для создания нужного набора данных.Мы используем уровень изоляции по умолчанию для фиксации чтения.

К моему удивлению, я регулярно нахожу, что этот запрос извлечения блокируется и выбирается в качестве жертвы.Я не думал, что SELECT в транзакции с фиксацией на чтение мог бы сделать это, но согласно этому ответу SO это возможно возможно: Может ли уровень изоляции с фиксацией чтения когда-либо привести к взаимоблокировке (Sql Server)?

С помощью флагов трассировки 1204 и 12222 я определил конфликтующее утверждение, а также объект и индекс, о которых идет речь.По сути, конкуренция происходит из-за страницы данных в первичном ключе одной из таблиц.Мне нужно извлечь из этой таблицы, используя соединение по ее ключу (поэтому я снимаю блокировку S), конфликтующий оператор выполняет INSERT и запрашивает блокировку IX на странице данных индекса.

(Примечание: вышеупомянутое SO говорит об этой проблеме, возникающей с некластеризованными индексами, но, похоже, это происходит в кластеризованном PK. По крайней мере, это то, во что я верю, основываясь на моей интерпретации тупикаинформация в журнале событий и свойстве «relatedObjectId».)

Вот мои ограничения:

  1. Конфликтующий оператор находится в зашифрованной хранимой процедуре, предоставленной третьей стороной как частьготовое программное обеспечение.Нет возможности получить открытый текст или изменить его.
  2. Я не хочу использовать «грязное чтение», так как мне нужны мои извлеченные данные для сохранения их целостности.
  3. Это не яснодля меня, как или если реструктуризация моего запроса извлечения может предотвратить это.Блокировка находится на ПК таблицы, которая меня больше всего интересует, и я не вижу альтернативы использованию PK.
  4. Я не против, чтобы мой запрос извлечения был жертвой, так как я предпочитаю этоза прерывание оперативного использования исходной системы.Однако это приводит к сбою выполнения служб SSIS, поэтому, если это так, я бы хотел более четкий и более изящный способ справиться с этой ситуацией.

Может кто-нибудь предложить способы, предпочтительнопредотвратить тупик или, если нет, то лучше обработать ошибку?

1 Ответ

0 голосов
/ 18 февраля 2019

Я предполагаю, что вы пытаетесь ВСТАВИТЬ в ту же таблицу, из которой ВЫ ВЫБИРАЕТЕ.Если нет, то скриншот вкладки потока данных будет полезен при определении проблемы.Если да, то вам повезло - у меня была эта проблема раньше.

Добавьте сортировку к потоку данных, поскольку это полностью блокирующее преобразование (см. Ниже о блокирующих преобразованиях).Это означает, что SELECT потребуется для завершения загрузки всех данных в буфер конвейера, прежде чем любые данные будут переданы в место назначения.В противном случае SSIS пытается вставить данные, когда есть блокировка таблицы / индекса.Возможно, вы сможете проявить креативность с помощью своих стратегий индексирования здесь (я не пробовал это).Но полностью блокирующее преобразование сделает свое дело и устранит необходимость в каких-либо дополнительных индексах для таблицы (и связанных с этим издержках).

Примечание: никогда используйте подсказки запроса NOLOCK при выбореданные из таблицы как попытка обойти это.Я никогда не пробовал этого и не собираюсь этого делать.Вы (королевский вы) рискуете вставить непереданные данные в ваш ETL.

Ссылка:

https://jorgklein.com/2008/02/28/ssis-non-blocking-semi-blocking-and-fully-blocking-components/

...