RepeatableRead, похоже, не блокируется для чтения - PullRequest
2 голосов
/ 18 марта 2011

У меня странная проблема.У меня есть таблица с первичным ключом, который создается в триггере INSTEAD OF.Вероятно, это худший способ реализации первичного ключа, но они в основном выбирают максимум, увеличивают его на 1 и используют это значение в качестве ключа.Это происходит вместо триггера.

У меня есть приложение .Net, которое запускает транзакцию RepeatableRead, и я вставляю запись в эту таблицу.Это прекрасно работает, пока я не пытаюсь сделать больше одной вставки одновременно.Если я это сделаю, я получу ошибку нарушения PK.Мне кажется, что обе вставки запускаются, триггер выбирает один и тот же последний номер для каждой транзакции, увеличивает его на 1, а затем пытается вставить обе записи с тем же новым «идентификатором».

I 'Мы поговорили с администратором базы данных, который установил этот триггер, и он считает, что RepeatableRead должен помешать этому, поскольку он, очевидно, блокирует таблицу для чтения, а другие транзакции будут ожидать освобождения блокировок.Так что, по сути, мои транзакции будут происходить в сериале.

Итак, вопрос в том, зачем мне получать нарушение PK, если RepeatableRead работает так, как его описал администратор БД?

Ответы [ 2 ]

1 голос
/ 18 марта 2011

RepeatableRead не исправит это, потому что он допускает фантомные вставки, что именно здесь и происходит.Вторая вставка неверна, потому что она не «видит» предыдущую вставку, и у вас есть описанное поведение.

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

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

1 голос
/ 18 марта 2011

сначала позвольте мне выразить свое отвращение к подходу, используемому для генерации первичного ключа, теперь, когда речь идет об изоляции REPEATABLE READ, она защищает только от обновлений, вы все равно сможете читать, и в этом проблема вашей реализации,никакой защиты от вставок либо

в идеале я не призываю реструктурировать генерацию первичного ключа, но если это невозможно, остается только использовать SERIALIZABLE изоляцию, которая защищает также и вставки, однако в зависимости от того, как и когдавы определяете следующее значение ключа, вы не сможете решить его в любом случае

...