如何使用MySQL后端在Hibernate save()调用上设置超时?

时间:2011-08-15 20:36:36

标签: java mysql database hibernate timeout

我们上周在一个基于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(...)可用于超时查询
  • 我见过JPA 2 javax.persistence.query.timeout,但我不完全确定它是我想要的(我也不认为我的Hibernate版本足够新)

这些似乎都不是我想做的(除了JPA 2之外)。这看起来应该非常简单。这里有什么我想念的吗?

谢谢!

3 个答案:

答案 0 :(得分:6)

之前我一直在寻找同样的东西,但是在后端而不是MySQL上使用Oracle。就我所见,在任何库中都没有任何机制,包括JDBC驱动程序。即使是你列出的超时,比如Transaction.setTimeout(),也没有达到你所期望的效果。他们只是等待数据库语句完成执行,然后如果超过给定的超时则抛出TimeoutException。如果你的查询只是无限期挂起,那就太没用了。我发现的唯一可能的开箱即用解决方案是在数据库本身上设置查询超时,这在Oracle上是一个全局设置,将影响对数据库的所有查询。这不是非常有用。据我所知,要做你正在寻找的东西,你必须启动一个单独的线程来计算它们的时间,并在它们达到超时时以某种方式中断它们。我从Oracle或任何与数据库相关的库/框架中都没有找到任何支持。

答案 1 :(得分:0)

如果问题是前端响应问题,您可以考虑以最适合您的方式异步运行数据库命中。然后你不会对后端的及时性感到满意。您可以使用JMS桥,或者如果您在Spring中,可以使用@Async或其他任何异步。

如果您正在运行EJB,则可以在容器上设置事务超时,或者如果您使用BMT,则在事务本身上设置事务超时。此设置将在超时后终止tx。

或者,您也可以在本地移动数据库。

答案 2 :(得分:-2)

  • hibernate.c3p0.timeout ex:300您指定超时期限(在本例中为300秒),之后将从池中删除空闲连接)。 hibernate.c3p0.idle_test_periods这是自动验证连接之前的时间(以秒为单位)。