我使用Hibernate 5.4.1.Final和Java 8。我通过以下方式将查询超时设置为TypedQuery
typedQuery.setHint("javax.persistence.query.timeout", 400);
字符串
但hib会将其转换为秒数并向下舍入为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秒?
谢谢
5条答案
按热度按时间yptwkmov1#
Hibernate本身并不处理这个超时,而是通过JDBC Statement. setvalid方法将它提供给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驱动程序提供的超时精度。这可能是预期的行为。
如果以秒为单位指定网络超时似乎更合适,因为很难避免随机的网络延迟。
nnvyjq4y2#
我们通过设置PostgreSQL DB的statement_timeout参数找到了一个解决方法。当我们需要限制查询执行时间时,我们执行以下脚本。当然超时值是可配置的。运行查询后我们将此参数设置为0。
字符串
w8ntj3qf3#
在调试了**(很多)Hibernate和我的(maria-db)JDBC连接器之后,我也遇到了同样的问题。
我注意到下面的**代码行(在hibernate-core中),它基本上迫使您使用MS格式的秒(例如1000)来提示'javax.persistence.query.timeout',否则,它将舍入值(value是提示的值)
这基本上意味着你不能有1-999毫秒,而是0或1秒
字符串
代码行取自此源代码
我希望你能找到一个解决方案,因为我找不到一个变通办法
编辑:
唯一的办法我可以拉这关闭是使用连接的网络超时。
请注意,由于这是**“手动”完成的,因此不会像Hibernate那样为您进行清理(关闭/释放资源),也不会调用KILL命令,因此您必须自己**进行清理
型
o7jaxewo4#
要为Hibernate管理的查询设置毫秒级的超时,您必须获得对Hibernate管理的JDBC连接的完全控制(而且,不,您不会被普通JDBC而不是Hibernate锁定)。
一种方法是实现你自己的
ConnectionProvider
。像往常一样,你想子类化你当前的ConnectionProvider
,假设它是股票DatasourceConnectionProviderImpl
,只覆盖两个方法:getConnection()
和closeConnection(Connection)
。字符串
由于
Connection
在概念上是无状态的,因此应该并且将被重用,因此有必要将其初始超时存储在ConcurrentMap
中,然后在Connection
关闭时恢复超时。选择用于超时设置的Executor
是一个普通的调用者,我们不需要任何更复杂的东西。多线程问题:
alteredConnections
是线程安全的,因为ConnectionProvider
当然是由应用程序中的多个线程同时访问的,但是没有更多的保护是必要的,因为Connection
不是由Hibernate在线程之间共享的。接下来,我们必须在Hibernate中注册我们的自定义
ConnectionProvider
。从5.3.9版开始,可以使用适当的ServiceContributor
实现来完成:型
,那么它应该在
META-INF/services/org.hibernate.integrator.spi.Integrator
classpath资源中注册:型
另一个很好的问题是如何定义
myTimeoutInMilliseconds
,因为它很可能已经被设置为每个Hibernate查询,Criteria等。这个问题没有简单的解决方案,因为在ConnectionProvider
级别无法访问这些示例。我能想到的唯一简单的方法是使用ThreadLocal
:将myTimeoutInMilliseconds
值注入到线程存储中,并在ConnectionProvider
级别检索它(不要忘记在关闭Connection
时清除ThreadLocal
的状态)。xxe27gdn5#
试试这个:
字符串