mysql:服务器重启后保持自动增量计数器 - 不一致的envers审计表

时间:2014-10-07 15:00:51

标签: java mysql hibernate innodb hibernate-envers

我在InnoDb上使用mysql 5.5架构。

mysql 5.5指南说明:

  

InnoDB使用内存中的自动递增计数器,只要服务器   运行。当服务器停止并重新启动时,InnoDB会重新初始化   第一个INSERT到表的每个表的计数器,如   如前所述。

这对我来说是个大问题。我正在使用envers来保持实体审核。我得到的错误与我删除的“最后一行”一样多。

假设我正在将数据插入到空表中。假设插入10行。然后假设删除最后一个8.在我的表中我将得到2个实体,分别为id 1和2。在审计表中,我将拥有所有10个实体,id为1到10:id为3到10的实体将有2个操作:创建操作和删除操作。

自动递增计数器现在在主表中设置为11。重新启动mysql服务自动增量计数器转到3.因此,如果我插入一个新实体,它将以id 3保存。但在审计表中已经有一个id为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生成的文件中没有关于autoincrement counter的信息。因此,恢复转储可能是个问题!

2 个答案:

答案 0 :(得分:0)

此类数据库的简单解决方案是使用软删除而不是物理删除。

软删除是指向表中添加字段的位置,该字段用作状态/指示符,以确定是否将行视为"活动"或"不活跃"。从这里,您将所有查询基于您的表,其中指标列等于"活动"哨兵价值,忽略不活跃的价值。

还有其他选项,但这很简单,也很容易实现。

答案 1 :(得分:0)

解决方案是将envers配置属性org.hibernate.envers.allow_identifier_reuse设置为true

它的作用是在添加具有相同ID的新条目时设置已删除的记录revend*列。因此,在具有相同ID和NULL revend的两条记录的情况下,您将不会获得条目。

当前记录可能仍然存在问题,其中有多个记录具有相同ID的NULL revend。不幸的是,此问题必须手动处理。这意味着您必须为这些记录自行设置revend,而将其中一个保留为NULL revend

另请参阅: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#envers-configuration