#django #postgresql
#django #postgresql
Вопрос:
Я использую Django 2.2, и мой вопрос таков: увеличивает ли transaction.atomic откат до последовательности pk?
Ниже приведена фоновая ошибка, которую я написал, которая привела меня к этой проблеме
Я столкнулся с действительно странной проблемой, которую не могу разгадать, и я надеюсь, что кто-то сталкивался с подобной проблемой.
Вставка, использующая функцию django ORM .create()
, возвращает django.db.utils.IntegrityError: duplicate key value violates unique constraint "my_table_pkey" DETAIL: Key (id)=(5795) already exists.
Прекрасно. Но потом я смотрю на таблицу, и никакой записи с id = 5795 не существует!
SELECT * from my_table where id=5795;
Шоу (0 rows)
Взгляд на последовательность my_table_id_seq
показывает, что она, тем не менее, увеличилась, чтобы показать last_value = 5795
, как если бы была вставлена вышеупомянутая запись. Более того, проблема возникает не всегда. Успешная вставка с другими данными вставляется с идентификатором = 5796. (Я попытался сбросить последовательность pk, но это ничего не дало, так как, похоже, это все равно не проблема)
Я совершенно озадачен этим, и это вызвало у нас много проблем на одном конкретном столе. Наконец , я понимаю , что вызов завернут transaction.atomic
и что конкретный сценарий может вызывать двойную вставку с тем же pk
самым .
Итак, моя теория такова: атомарная транзакция не откатывает приращение
Комментарии:
1. Для транзакции не имело бы смысла откатывать последовательность, что, если транзакция занимает много времени для фиксации и происходит другая вставка, какой идентификатор должен принимать вторая вставка и как на нее повлияет откат?
2. Последовательность PostgreSQL не приведет к этой ошибке. Кажется, ваша библиотека приложений (в данном случае django) становится «креативной» и делает что-то еще за кулисами.
3. Когда вы смотрите
my_table_id_seq
, также важно посмотреть на значение вis_called
поле. Гдеt
означает, что следующее используемое число будет большеlast_value
,'f
last_value
чем будут использоваться средства и. Чтобы получить полезный ответ, вам нужно будет предоставить код, который происходит вtransaction.atomic
. Добавьте в качестве обновления к вашему вопросу.4. Я должен был добавить, что последовательности Postgres не откатываются. Каждый раз, когда к ним прикасается оператор, они продвигаются независимо от того, выполняется ли оператор успешно или нет. В дополнение к коду в
transaction.atomic
модели, над которой ведется работа, было бы неплохо добавить к вопросу.5. Привет @AdrianKlaver, ваш ответ решает это для меня, потому что, если то, что вы говорите, верно, тогда я знаю, что в моем коде вызывает это (поэтому сохраню его в объеме, исключив эту часть). Не могли бы вы написать ответ с учетом вышеизложенного и с вашим пониманием того, почему он не откатывается, и я приму его.
Ответ №1:
Последовательности Postgres не откатываются. Каждый раз, когда к ним прикасается оператор, они продвигаются независимо от того, выполняется ли оператор успешно или нет. Для получения дополнительной информации см. Раздел Примечания здесь Создать последовательность.