我使用Hibernate 5.4.1.Final和Java8。我通过
将查询超时设置为TypedQuery。typedQuery.setHint("javax.persistence.query.timeout", 400);
但是休眠状态将其转换为秒,并四舍五入为0。当我得到提示时
typedQuery.getHints();
{org.hibernate.timeout=0, javax.persistence.query.timeout=0}
如果我将某项设置为500以上,则舍入为1秒。
typedQuery.setHint("javax.persistence.query.timeout", 500);
typedQuery.getHints();
{org.hibernate.timeout=1, javax.persistence.query.timeout=1000}
如何设置以毫秒为单位且小于1秒的查询超时?
谢谢。
答案 0 :(得分: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驱动程序提供的超时准确性。这很可能是预期的行为。
如果无论如何以秒为单位指定,网络超时似乎更合适,因为随机网络延迟很难避免。
答案 1 :(得分:0)
我们通过设置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");
}
});
答案 2 :(得分:0)
在调试(很多)休眠和我的(maria-db)JDBC连接器之后,我遇到了完全相同的问题。
我注意到下面的代码行(在休眠内核中),这基本上迫使您使用MS格式的秒数(例如1000)作为提示“ javax.persistence.query.timeout”,否则,它将将舍入该值(值是提示的值)
这基本上意味着您不能有1-999毫秒,而只能是0或1秒
int timeout = (int)Math.round( ConfigurationHelper.getInteger( value ).doubleValue() / 1000.0 );
Code line was taken from this source code
我希望您能找到解决方案,因为我找不到解决方法
编辑:
我能做到这一点的唯一方法是使用连接的网络超时。
请注意,由于此操作是“手动” 完成的,因此不会像冬眠(关闭/释放资源)那样为您进行清理(也不会调用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();
答案 3 :(得分:-2)
尝试一下:
typedQuery.setHint("org.hibernate.timeout", "1");
typedQuery.getSingleResult();