mysql: сохранить счетчик автоинкремента после перезапуска сервера - несогласованные таблицы аудита envers

Я использую схему InnoDb на mysql 5.5.

mysql 5.5 руководство сообщает:

InnoDB использует счетчик автоинкремента в памяти, пока работает сервер. Когда сервер останавливается и перезапускается, InnoDB повторно инициализирует счетчик для каждой таблицы для первого INSERT в таблицу, как описано ранее.

Это большая проблема для меня. Я использую envers для аудита сущностей. Я получаю столько ошибок, сколько «последних строк» ​​удаляю.

Предположим, я начинаю вставлять данные в пустую таблицу. Предположим, что нужно вставить 10 строк. Затем предположим удалить последние 8. В моей таблице у меня будет 2 объекта с идентификаторами 1 и 2 соответственно. В таблице аудита у меня будут все 10 объектов с идентификатором от 1 до 10: у объектов с идентификатором от 3 до 10 будет 2 действия: создать действие и удалить действие.

счетчик автоинкремента теперь установлен на 11 в основной таблице. Перезапуск счетчика автоинкремента службы mysql становится равным 3. Поэтому, если я вставлю новый объект, он будет сохранен с идентификатором 3. Но в таблице аудита уже есть объект с идентификатором = 3. Этот объект уже помечен как созданный и удаленный . Это приводит к ошибке утверждения во время действия обновления/удаления, поскольку envers не может обработать это несогласованное состояние.

ERROR org.hibernate.AssertionFailure - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.RuntimeException: Cannot update previous revision for entity Customer_H and id **.

Есть ли способ изменить это поведение и сохранить значения автоинкремента при перезапуске сервера?

Насколько я помню, в сгенерированном файле mysqldump нет информации о счетчике автоинкремента. Так что восстановление дампа тоже может быть проблемой!


person gipinani    schedule 07.10.2014    source источник
comment
Есть проблема? Он не будет повторно инициализировать счетчик с 0, если вы об этом думаете.   -  person N.B.    schedule 07.10.2014
comment
Большая проблема @N.B. Я использую таблицу аудита с envers. Я получаю столько ошибок, сколько последних строк я удаляю. Потому что, когда я создаю новую строку в основной таблице, в таблице аудита этот идентификатор уже существует.   -  person gipinani    schedule 07.10.2014
comment
Я вижу, это означает, что то, что я прокомментировал ранее, неверно и должно быть проигнорировано. Я должен признать, что у меня не было этой проблемы (и я перезапускал MySQL более чем часто). Просто чтобы убедиться, что вы просто перезапускаете службу MySQL и ничего с ней не делаете - она ​​пытается запустить auto_increment с самого начала или вы каким-то образом пытаетесь сбросить его вручную?   -  person N.B.    schedule 07.10.2014
comment
Спасибо @N.B. за ваш комментарий. Я обновил свой вопрос! Я не пытаюсь сбросить его вручную. Это mysql, который пересчитывает его счетчик   -  person gipinani    schedule 07.10.2014


Ответы (2)


Простое решение для этого типа базы данных — использовать обратимое удаление, а не физическое удаление.

Мягкое удаление — это когда вы добавляете поле в свою таблицу, которое действует как статус/индикатор того, считается ли строка «активной» или «неактивной». Исходя из этого, вы основываете все свои запросы на своей таблице, где столбец индикатора равен «активному» сигнальному значению, игнорируя неактивные.

Возможны и другие варианты, но этот достаточно прост и легко реализуем.

person Naros    schedule 02.06.2017

Решение состоит в том, чтобы установить для свойства конфигурации envers org.hibernate.envers.allow_identifier_reuse значение true.

Что он делает, так это устанавливает столбцы удаленных записей revend* при добавлении новой записи с тем же идентификатором. Таким образом, вы не получите записи, в которых есть две записи с одинаковым идентификатором и NULL revend.

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

См. также: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#envers-configuration

person Seiya    schedule 11.04.2020