如何在休眠时将查询超时设置为小于 1 秒



我使用Hibernate 5.4.1.Final和Java 8。我将查询超时设置为类型化查询

typedQuery.setHint("javax.persistence.query.timeout", 400);

但休眠将其转换为秒并向下舍入为 0。当我得到提示时

typedQuery.getHints();
{org.hibernate.timeout=0, javax.persistence.query.timeout=0}

如果我将 sth 设置为 500 以上,它会四舍五入到 1 秒。

typedQuery.setHint("javax.persistence.query.timeout", 500);
typedQuery.getHints();
{org.hibernate.timeout=1, javax.persistence.query.timeout=1000}

我们如何设置毫秒且小于 1 秒的查询超时?

谢谢。

Hibernate本身不处理此超时,而是通过JDBC Statement.setTimeout方法将其提供给JDBC驱动程序。(见:https://thoughts-on-java.org/11-jpa-hibernate-query-hints-every-developer-know/(

另请参阅此问题 https://bugs.eclipse.org/bugs/show_bug.cgi?id=456067。

似乎只要 JDBC 驱动程序仅提供为此配置指定秒数,Hibernate 就会被迫将此值转换为秒。请检查 JDBC 驱动程序提供的超时准确性。这很可能是预期的行为。

无论如何,如果以秒为单位指定网络超时似乎更合适,因为随机网络延迟很难避免。

我们通过设置 Postgresql DB 的参数找到statement_timeout解决方法。当我们需要限制查询执行时间时,我们执行以下脚本。确保超时值是可配置的。运行查询后,我们将此参数设置为 0。

Session session = entityManager.unwrap(Session.class);
session.doWork(new Work() {
    @Override
    public void execute(Connection connection) throws SQLException {
        connection.createStatement().execute("set statement_timeout = 300");
    }
});

在调试(很多(休眠和我的(maria-db(JDBC连接器后,我遇到了同样的问题。

我注意到下面的代码行(在休眠核心中(,它基本上迫使您使用 MS 格式的秒(例如 1000(作为提示"javax.persistence.query.timeout",否则,它将舍入值(值是提示的值(

这基本上意味着你不能有 1-999 毫秒,而是 0 或 1 秒

int timeout = (int)Math.round( ConfigurationHelper.getInteger( value ).doubleValue() / 1000.0 );

代码行取自此源代码

我希望你能找到一个解决方案,因为我找不到解决方法

编辑:

我能做到这一点的唯一方法是使用连接的网络超时。

请注意,由于这是"手动">完成的,因此不会像休眠那样为您进行清理(关闭/释放资源(,也不会调用 KILL 命令,您必须自己完成

int timeoutMs = 250;
var connection = jdbcTemplate.getDataSource().getConnection();
connection.setNetworkTimeout(Runnable::run, timeoutMs);
var callableStatement = connection.prepareCall("{call testSp()}");
// Setup your SP parameters
callableStatement.execute();

试试这个:

typedQuery.setHint("org.hibernate.timeout", "1");
typedQuery.getSingleResult();

相关内容

  • 没有找到相关文章

最新更新