我使用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();