Изменение переменных сеанса Oracle вне транзакции Hibernate - PullRequest
0 голосов
/ 12 февраля 2019

Некоторое время мы использовали подобный шаблон, чтобы обеспечить выполнение определенной операции с 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, которыйне обновлять / удалять или возвращать результаты вне транзакции?

1 Ответ

0 голосов
/ 13 февраля 2019

Использование базового соединения напрямую обходит проверки 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'")
    );
}
...