Мертвая блокировка, создаваемая двумя SQL-соединениями, каждое из которых использует транзакции, разные таблицы, ограничение внешнего ключа между двумя таблицами - PullRequest
4 голосов
/ 20 ноября 2008

Окружающая среда

Я работаю над приложением C ++, которое использует собственный клиент SQL 9.0 для связи с базой данных SQL Server 2000.

Сценарий

  • 2 соединения открыты к СУБД
  • Каждое соединение настроено на использование транзакций
  • Запрос по Connection1 работает с TableA
  • Запрос по Connection2 работает с TableB
  • TableB имеет ограничение внешнего ключа для поля key_id в TableA

Я построил функцию, которая делает следующее:

begin a transaction on Connection1 & Connection2
prepare a query in TableA on Connection1
prepare a query on TableB on Connection2

begin loop over some_data
   (1) insert into key_id on TableA

   begin loop over some_other_data
      (2) insert into TableB using same key_id as in Table A
   end loop
end loop

commit on Connection1
commit on Connection2

Я столкнулся с тем, что запрос (1) успешно выполняется, но как только SQLExecute вызывается для запроса (2), отладчик отключается никогда.

Вопрос

Правильно ли я диагностирую проблему, связанную с тупиковой блокировкой?

Я понял, что поскольку Connection 1 создает ключ в TableA, но не фиксирует его, то Connection2 пытается добавить информацию к TableB, что из-за ограничения внешнего ключа должен иметь ключ присутствует в TableA. Из-за этого SQLExecute блокирует запрос, ожидая завершения транзакции на TableA, чего он не может сделать, пока TableB не завершит свою запись, благодаря тому, как был написан код.

Дополнительные примечания

Я могу написать код этой проблемы, но хочу убедиться, что мое понимание проблемы правильное.

1 Ответ

7 голосов
/ 20 ноября 2008

Ограничение внешнего ключа для TableB против TableA должно проверить, чтобы подтвердить существование ключа. Затем он примет или отклонит запись TableB.

Поскольку запись TableA, содержащая ключ (еще не подключена), еще не зафиксирована, ограничение внешнего ключа должно ждать - вставка не вернется, пока запись TableA не будет зафиксирована или откатана.

Поскольку фиксация на первом соединении ожидает возврата вставки TableB ... у вас тупик.

Другими словами, вы правы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...