Oracle. Как не нужно генерировать первичный ключ
Идея поста возникал при прочтении Получение в программе значения первичного ключа после INSERT.
В Oracle младше 12 версии нет автоинкрементного поля. Стандратный способ генерации первичных ключей — последовательности. Но иногда разработчики генерируют первичный ключ таким способом:
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. Иначе будут возникать ошибки.