【问题标题】:Alter Oracle session variables outside of a Hibernate transaction在 Hibernate 事务之外更改 Oracle 会话变量
【发布时间】:2019-02-12 18:52:06
【问题描述】:

出于性能原因,我们一直在使用这样的模式来确保使用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 执行既不更新/删除也不返回结果的本机查询?

【问题讨论】:

  • 谢谢尼克。您提到尝试使用查询方法。我犹豫要问,但是执行一个不纯的查询会满足您的要求,这会改变会话作为副作用吗?

标签: java oracle hibernate hibernate-5.x


【解决方案1】:

使用底层 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'")
    );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2010-12-04
    • 2011-04-14
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多