Почему элемент последовательности Postgres увеличивается, даже если создание объекта не удается? - PullRequest
0 голосов
/ 01 июня 2018

У меня есть элемент Postgres, где одна из моих моделей Клиент просто проиндексирована по первичному ключу.У меня возникла проблема с созданием клиентов, потому что где-то по ходу дела кто-то создал клиента, в то время как явная установка его первичного ключа, который я прочитал, не влияет на таблицу последовательности Postgres для клиентов, которая отвечает за автоматическое увеличение первичного ключа 1 всякий раз, когдаКлиентский объект создан.

Я запустил несколько SQL-запросов, чтобы поиграть с ним, и обнаружил, что текущее значение последовательности на самом деле на 1 ниже, 262, чем самый высокий идентификатор для Клиентов в базе данных 263, поэтому он говорил, что Клиент сID 263 уже существовал.Я попытался создать клиент в нашем приложении переднего плана, снова получил ошибку и решил снова выполнить запросы.Я увидел, что в базе данных не было создано нового клиента, как и ожидалось, но я также заметил, что значение последовательности увеличилось до 263, поэтому, когда я снова попытался создать клиента, это сработало!

Это нормально?поведение приращения таблицы последовательности PostgreSQL, даже если создание связанной модели не удается?Если так, то это может вызвать серьезные проблемы.

1 Ответ

0 голосов
/ 01 июня 2018

Да, это ожидаемое поведение. См. Документы :

nextval

Переместить объект последовательности к его следующему значению и вернуть это значение.Это делается атомарно: даже если несколько сеансов выполняются следующим образом одновременно, каждый из них безопасно получит отдельное значение последовательности.

Если объект последовательности был создан с параметрами по умолчанию, последовательные вызовы nextval будут возвращать последовательные значения, начинающиеся с 1.Другие варианты поведения могут быть получены с помощью специальных параметров в команде CREATE SEQUENCE;см. страницу справочника по командам для получения дополнительной информации.

Важно: Чтобы избежать блокировки параллельных транзакций, которые получают числа из той же последовательности, операция nextval никогда не откатывается;то есть, после того как значение было получено, оно считается использованным, даже если транзакция, которая выполняла nextval, позже прерывается.Это означает, что прерванные транзакции могут оставить неиспользованные «дыры» в последовательности назначенных значений.

Обратите внимание, что nextval обычно устанавливается в качестве значения по умолчанию для столбца автоинкремента / последовательного порта.

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

Если это так, то это может вызвать серьезные проблемы.

Как что?Проблема в вашем случае заключалась в том, что кто-то вручную указал значение для столбца автоинкремента.Вы никогда не должны делать это, если вы не самурай.:)

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