Oracle. Как не нужно генерировать первичный ключ
Идея поста возникал при прочтении Получение в программе значения первичного ключа после INSERTopen in new window.
В Oracle младше 12 версии нет автоинкрементного поля. Стандратный способ генерации первичных ключей — последовательностиopen in new window. Но иногда разработчики генерируют первичный ключ таким способом:
select max(rid) + 1 from table
Это приводит к проблемам при многопользовательской работе. Типичная ситуация — пользователи одновременно получают новое значение для ПК, а потом вставляют записи:
Пользователь1 | Пользователь2 |
---|---|
select max(rid) + 1 from table | |
select max(rid) + 1 from table | |
insert | |
insert |
В результате второй пользователь зависает из-за блокировки. Если же первый пользователь зафиксирует данные, то у второго сработает ограничение по первичному ключу:
Пользователь1 | Пользователь2 |
---|---|
select max(rid) + 1 from table | |
select max(rid) + 1 from table | |
insert | |
insert | |
commit | |
ORA-00001: нарушено ограничение уникальности |
Для генерации ПК следует использовать последовательности или специальные механизмы вроде GUID. Иначе будут возникать ошибки.