繁体   English   中英

如何在 Hibernate 中将查询超时设置为小于 1 秒?

[英]How to set query timeout less than 1 second at Hibernate?

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

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");
    }
});

在调试(很多) hibernate 和我的(maria-db)JDBC 连接器之后,我有同样的问题。

我注意到下面的这个代码行(在 hibernate-core 中)它基本上强制您使用 MS 格式的秒数(例如 1000)作为提示 'javax.persistence.query.timeout' 否则,它将舍入该值(值是提示的值) )

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

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

代码行取自此源代码

我希望您能找到解决方案,因为我找不到解决方法

编辑:

我可以解决这个问题的唯一方法是使用连接的网络超时。

请注意,由于这是“手动”完成的,因此不会像 hibernate 那样为您完成清理工作(关闭/释放资源),也不会调用 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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM