Иногда мне нужно получить уникальный идентификатор и сохранить его с записью, но я не могу использовать столбец идентификаторов. Поэтому вместо этого у меня есть таблица, которая предоставляет уникальные идентификаторы, используя поле метки и целое число. Когда требуется уникальный идентификатор, я вызываю хранимую процедуру и передаю метку, и она выплевывает следующий связанный с ней идентификатор.
Конечно, важно, чтобы это было надежно в среде с параллельными транзакциями. То есть хранимая процедура никогда не должна возвращать одно и то же значение дважды для данной метки. Мое ограниченное понимание изоляции транзакций заставило меня сделать следующее:
1) Установить уровень изоляции транзакции на сериализуемый
2) ВЫБЕРИТЕ ИД С меткой UniqueIdTable WHERE = @ inputLabel
3) ОБНОВЛЕНИЕ UniqueIdTable SET id = id + 1 WHERE label = @ inputLabel
4) Вернуть идентификатор, полученный в 2)
Но действительно ли это безопасно? Возможно ли одновременное выполнение двух потоков до шага 2), даже с сериализуемой изоляцией? Насколько я понимаю, самый высокий уровень изоляции гарантирует только то, что одна транзакция будет выполняться без появления фантомных строк или изменения данных из других потоков. В этом случае два одновременных вызова функции GetID могут возвращать одно и то же значение.
Я что-то неправильно понимаю об уровнях изоляции? Как я могу гарантировать, что этого не произойдет?
У меня есть еще одна проблема, с которой мне нужно разобраться. Предположим, у меня есть таблица с полем, в котором хранятся внешние ключи для второй таблицы. Первоначально записи в первой таблице не имеют соответствующей записи во второй таблице, поэтому я сохраняю NULL в этом поле. Теперь в какой-то момент пользователь запускает операцию, которая сгенерирует запись во второй таблице и на нее ссылается первая таблица. Это всегда отношение один-к-одному, поэтому, если два пользователя одновременно пытаются сгенерировать запись, создается и связывается одна запись, а другой пользователь получает сообщение о том, что запись уже существует.
Как я могу убедиться, что дубликаты не создаются в параллельной среде?