mysql: keep auto-increment counter after server restart - inconsistent envers audit tables

China☆狼群 提交于 2021-02-06 14:01:35

问题


I'm using InnoDb schema on mysql 5.5.

mysql 5.5 guide states:

InnoDB uses the in-memory auto-increment counter as long as the server runs. When the server is stopped and restarted, InnoDB reinitializes the counter for each table for the first INSERT to the table, as described earlier.

This is a big problem for me. I'm using envers to keep entities audits. I get as many errors as many "last rows" I delete.

Suppose I'm starting insert data into an empty table. Suppose to insert 10 rows. Then suppose to delete the last 8. In my table I will have as result 2 entities, with id 1 and 2 respectively. In the audit table I will have all 10 entities, with id from 1 to 10: entities with id from 3 to 10 will have 2 action: create action and delete action.

auto-increment counter is now setted to 11 in main table. Restarting mysql service auto-increment counter goes to 3. So if I insert a new entity, it will be saved with id 3. But in audit table there is already an entity with id = 3. That entity is already marked as created and deleted. It result in an assertion failure during update /delete action because envers cannot handle this inconsistent state.

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 **.

Is there a way to change this behaviour and keep auto-increment values while restarting server?

As I remember also in mysqldump generated file there is no infos about autoincrement counter. So also restoring a dump could be a problem!


回答1:


An easy solution for this type of database is to utilize soft-deletes rather than physical deletes.

A soft delete is where you add a field to your table that acts as a status/indicator as to whether the row is considered "active" or "inactive". From this, you base all your queries to your table where the indicator column equals the "active" sentinel value, ignoring the inactive ones.

There are other options available, but this is simple and easy enough to implement.




回答2:


The solution is to set the envers configuration property org.hibernate.envers.allow_identifier_reuse to true.

What it does is setting the deleted records revend* columns when a new entry with the same ID is being added. So you won't get entries where there are two records with the same ID and NULL revend.

There might still be an issue with current records where there is more than one record with NULL revend for the same ID. This issue, unfortunately, has to be handled manually. This means that you have to set the revend by yourself for those records leaving just one with NULL revend.

See also: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#envers-configuration



来源:https://stackoverflow.com/questions/26239083/mysql-keep-auto-increment-counter-after-server-restart-inconsistent-envers-au

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!