当前位置: 首页 > 面试题库 >

Hibernate使用hibernate.jdbc.batch_versioned_data保存陈旧数据

南宫松
2023-03-14
问题内容

环境

hibernate4.2

ojdbc6-Oracle 11.2.0.3.0 JDBC 4.0

Oracle数据库11g

问题

我们遵循了许多建议,以如下方式配置Hibernate批处理:

<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>

我们检查了日志,发现生成的SQL语句已批处理。但是,如果两个事务同时修改相同版本的实体行,则Hibernate将成功提交它们,导致最后提交的事务中的冲突更新丢失(两个事务中都保存了无冲突的数据,因此最后一个事务离开了数据库)处于不一致状态)。

令人惊讶的是,关于此行为的文档很少。Hibernate官方文档说:

hibernate.jdbc.batch_versioned_data

如果您的JDBC驱动程序从executeBatch()返回正确的行数,则将此属性设置为true。通常可以安全地打开此选项。然后,Hibernate将使用批处理DML来自动版本化数据。默认为false。

通常安全 吗?在通知整个版本已损坏之前,我们几乎将其发送到了生产环境。

我们搜寻了五年前发布的博客,描述了这种怪异。显然,Hibernate很长时间没有对此做任何事情。

Hibernate为何如此表现?它从jdbc驱动程序获得信息,即更新的行数未知,为什么它不抛出异常来指示它,却给人留下版本检查已成功通过的印象?


问题答案:

oracle驱动程序应返回正确的行数。如果不是这种情况,我会感到惊讶。您能够确认驱动程序的结果正确吗?您可以打开Hibernate日志记录进行检查。

需要检查的几件事:

  1. 记录发送到数据库的实际SQL,并检查where子句中是否提到了version列。不确定是否通过批处理启用的Hibernate登录来记录SQL,然后您可能不得不采用另一种方式记录SQL(例如,p6spy)

  2. 如果在并发更新期间正确返回了行计数,则该应用程序运行正常。通过检查版本列的值是否已更新来更正此内容。

更新 根据以下链接,此问题在11g之前的Oracle驱动程序中一直存在,并已在版本12c中修复

https://hibernate.atlassian.net/browse/HHH-3360

对于以前的Oracle版本,还有一些其他有用的信息,即提供了自定义解决方案

其他资源:https:
//hibernate.atlassian.net/browse/HHH-5070



 类似资料:
  • 问题内容: 快速版本 基本上,我正在更新hibernate表,后续查询正在加载陈旧的值。 详细版本 hibernate(3.3.1.GA)和EhCache(2.4.2)。 包含页面的持久对象,我将页面添加到本书的中间。我正在使用Databinder / Wicket,尽管我认为这并不相关。 适用的字段/方法是: 最终结果是,有一个新页面添加到列表中,并且数据库也进行了相应更新,我已经在我的数据存储

  • 在Autoconf的第2版,大部分宏被重新命名以使用更加统一和具有描述性的命名方案。下面是被重新命名了的宏的原来名字, 随后给出了这些宏现在的名字。虽然为了保持向后兼容,旧名字仍然能够被autoconf程序所接受,旧名字都 被看作过时的。关于新的命名方案,参见 宏名 。AC—ALLOCAAC—FUNC—ALLOCA AC—ARG—ARRAY 因为用途有限而被删除了。AC—CHAR—UNSIGNED

  • 我在SpringBoot2中使用Hibernate5.3和Hikari2.7,通过官方的JDBC驱动程序使用FileMaker16数据源。 FileMaker服务器性能较差,SQL查询执行时间对于大表可以达到一分钟。有时,当连接池充满从未释放的活动连接时,它会导致连接泄漏。 问题是如何强制挂在池中的活动连接关闭,比如两分钟,将它们闲置并再次使用。 例如,我使用: 在raw中调用几次会导致连接泄漏,

  • 问题内容: 我正在尝试使用hibernate将数据插入数据库。这是我要执行的动作 但这给我一个错误的说法 线程“主”中的异常org.hibernate.TransientPropertyValueException:非null属性引用了一个瞬态值- 必须在当前操作之前保存瞬态实例 这是我的学生详细信息实体 我的学生详细信息hbm.xml 我的主题实体看起来像 Subject.hbm.xml 这是S