【发布时间】:2014-11-30 11:12:21
【问题描述】:
我正在使用 Hibernate 的 StatelessSession 批量插入和更新行。不确定jdbc.batch_size 是否与问题有关,但无论如何在我的应用程序中,我根本没有配置hibernate.jdbc.batch_size 参数。
我向会话提供一个连接对象,该对象已经线程绑定到现有事务(由 Spring 管理)。这是通过 Spring 的DataSourceUtils 完成的。出于这个原因,当我处理完数据后,我不会关闭无状态会话,因为在事务完成之前,我仍然需要为其他一些事情打开连接。
基本上是这样的:
statelessSession = sessionFactory.openStatelessSession(DataSourceUtils.getConnection(...));
// repeat many times
try {
statelessSession.insert(entity);
}
catch (ConstraintViolationException e) {
statelessSession.update(entity);
}
// some more actions
// close transaction
在 SQL Server 上,一切正常。每个 session.insert(...) 调用都会运行 SQL,如果我尝试插入现有行,可能会在唯一约束上失败。当我最终提交事务时,一切都按我的预期进行。
但是,在 Oracle 上,什么也没有发生。 Hibernate 日志打印 SQL,但它根本不运行。此外,插入不会在应该失败的时候失败。
调试Hibernate代码后,发现与JDBC批处理行为有关。我决定使用managedFlush() 方法显式刷新statelessSession。即便如此,我发现我必须在每个命令之后刷新它,否则它不会表现出我想要的快速失败行为。
statelessSession = sessionFactory.openStatelessSession(DataSourceUtils.getConnection(...));
// repeat many times
try {
statelessSession.insert(entity);
((Context) session).managedFlush()
}
catch (ConstraintViolationException e) {
statelessSession.update(entity);
((Context) session).managedFlush()
}
// some more actions not related to statelessSession
// close transaction
虽然这可行,但当我分析我的代码时,我发现它现在运行速度较慢。即使在可能与 managedFlush() 方法无关的 SQL Server 上。
知道发生了什么吗?是否有任何隐藏的配置我可以调整以实现所需的行为 - 例如“自动刷新”(但当然没有自动提交)?
【问题讨论】:
标签: java spring oracle hibernate orm