SQL Server возвращает неполные данные из завершенной транзакции - PullRequest
0 голосов
/ 24 января 2019

У меня есть два приложения на C # (назовем их Writer и Reader), использующих базу данных SQL Server.

Writer запускает транзакцию Repeatable Read, вызывает хранимую процедуру для вставки записи в таблицу (назовите ее Parent), а затем ноль или более раз вызывает другую хранимую процедуру для вставки связанных записей в другую таблицу (назовите ее Child) , а затем фиксирует транзакцию.

Reader вызывает хранимую процедуру, которая выбирает новые записи из Parent с левым внешним соединением в Child (используя WITH (UPDLOCK, HOLDLOCK) в Parent), для которых столбцы, приходящие из Child, являются нулевыми, только когда были вставлены нулевые дочерние записи.

Я озадачен и напуган следующей воспроизводимой последовательностью событий:

  1. Writer начинает транзакцию.
  2. Writer вставляет в Parent.
  3. Считыватель вызывает свою хранимую процедуру, которая блокируется из-за ожидающей транзакции.
  4. Писатель вставляет в Child.
  5. Writer фиксирует транзакцию.
  6. Reader возвращает строку, в которой столбцы из дочерней таблицы имеют значение NULL; успешно записанные данные в дочерней таблице фактически потеряны , хотя последующие запросы показывают, что они были успешно записаны.

Как для Читателя получить данные от Родителя, но не от Ребенка, если записи Родителя и Ребенка находятся в одной транзакции?!

(Я попытался исключить подсказку HOLDLOCK для Parent в хранимой процедуре Reader и добавить SERIALIZABLE SET TRANSACTION ISOLATION LEVEL, но все, что он сделал, это начало генерировать взаимные блокировки.)

Дополнительный вывод 28 января 2019 г .: Эта проблема возникает только в моем симуляторе нагрузочных испытаний, когда изначально установлено соединение с базой данных; когда соединение извлекается из пула соединений .NET, данные извлекаются, как и ожидалось. Отключение пула с помощью SqlConnection.ClearPool (con); приводит к возникновению проблемы даже после первого подключения.

...