Выполняет транзакцию.атомарный откат приращений к последовательности pk

#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 не откатываются. Каждый раз, когда к ним прикасается оператор, они продвигаются независимо от того, выполняется ли оператор успешно или нет. Для получения дополнительной информации см. Раздел Примечания здесь Создать последовательность.