我如何在带有MySQL后端的Hibernate save()调用中设置超时?
我们上周在一个基于Java,Hibernate的大型系统中遇到了一个问题。 我们的后端MySQL数据库(托管在Amazon RDS上)在5-10分钟内无响应(它仍然会接受连接,但由于硬件问题,其写入吞吐量降为零)。 这段代码:
getSession().save(entity); //session is an instance of org.hibernate.Session
挂起约8.5分钟。 所以很明显,在这个陈述中需要某种超时条件,以便在我的特定情况下失败。 我不能保证我将来不会看到类似的硬件问题。
我应该提到我对Hibernate还是一个相当新的东西,所以有可能我不明白使用save()
与使用Criteria,Transactions等之间的关联。所以我发现了以下内容:
hibernate.c3p0.timeout
来设置C3P0连接池上的连接超时 getSession().getTransaction().setTimeout(...)
可用于超时事务 getSession().createQuery(...).setTimeout(...)
可用于超时查询 javax.persistence.query.timeout
,但我不完全确定它是我想要的(我也不认为我的Hibernate版本足够新) 这些都不是我想要做的(除了JPA 2之外)。 这看起来应该很简单。 有什么我在这里失踪?
谢谢!
我之前也在寻找这种类似的东西,但是在后端使用Oracle而不是MySQL。 据我所见,在任何库中都没有任何机制,包括JDBC驱动程序。 即使你列出的超时,比如Transaction.setTimeout(),也不会达到你所期望的。 他们只是等待数据库语句完成执行,然后如果它超出给定的超时时间,则会引发TimeoutException。 如果你有一个无限期悬挂的查询,那就没用了。 我发现的唯一潜在的现成解决方案是在数据库本身设置查询超时,这在Oracle上是一个全局设置,并且会影响对数据库的所有查询。 这不是非常有用。 据我所知,要做你正在寻找的东西,你必须开始一个单独的线程来定时查询它们,并且当它们超时时以某种方式打断它们。 我从来没有找到任何支持Oracle或任何与数据库相关的库/框架。
如果问题是前端响应问题之一,则可以考虑以任何最适合您的方式异步运行数据库匹配。 那么你就不会屈从于后端的及时性。 您可以使用JMS桥,或者如果您在Spring中,则可以使用@Async
或其他任何异步方式。
如果您正在运行EJB,则可以在事务本身上设置容器上的事务超时,或者如果您正在使用BMT。 该设置会在超时后终止tx。
或者,您也可以在本地移动数据库。
上一篇: How can I set a timeout on a Hibernate save() call with a MySQL backend?