出于性能原因,我们一直在使用这样的模式,以确保使用BATCH NOWAIT
执行特定操作。
try {
session.createSQLQuery("ALTER SESSION SET COMMIT_LOGGING='BATCH' COMMIT_WAIT='NOWAIT'").executeUpdate();
// Do the operation (which also calls transaction.commit())
return callback.apply(session);
} finally {
session.createSQLQuery("ALTER SESSION SET COMMIT_LOGGING='IMMEDIATE' COMMIT_WAIT='WAIT'").executeUpdate();
}
这在Hibernate 4中运行良好。从Hibernate 5开始,最后一个语句失败了,因为它不在事务中(因为它刚刚被提交)。
javax.persistence.TransactionRequiredException:执行更新/删除查询
它不是更新或删除,但executeUpdate()
是您可以调用以执行此语句而不返回任何行的唯一方法。它不应该在事务中,因为会话变量适用于整个连接,并且由于正在使用连接池,因此需要执行它以恢复会话变量。
我尝试使用其中一种查询方法,但是这个语句有-1行,它不会让我在最后堆叠SELECT 1 FROM DUAL
。
有没有办法从Hibernate执行本地查询,在事务之外既不更新/删除也不返回结果?
使用底层Connection直接绕过Hibernate的检查,并允许我安静地执行这样的声明。
try {
session.doWork(conn ->
conn.createStatement().execute("ALTER SESSION SET COMMIT_LOGGING='BATCH' COMMIT_WAIT='NOWAIT'")
);
return callback.apply(session);
} finally {
session.doWork(conn ->
conn.createStatement().execute("ALTER SESSION SET COMMIT_LOGGING='IMMEDIATE' COMMIT_WAIT='WAIT'")
);
}