有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用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()与使用条件、事务等之间的关联。因此我发现了以下几点:

  • hibernate.c3p0.timeout可用于设置C3P0连接池上的连接超时
  • getSession().getTransaction().setTimeout(...)可用于使事务超时
  • getSession().createQuery(...).setTimeout(...)可用于使查询超时
  • 我看过JPA2javax.persistence.query.timeout,但我不完全确定它是我想要的(我也不认为我的Hibernate版本足够新)

这些似乎都不是我想要做的(除了JPA2)。这看起来应该很简单。这里有我遗漏的东西吗

谢谢


共 (3) 个答案

  1. # 1 楼答案

    • 冬眠。c3p0。timeout ex:300指定从池中删除空闲连接的超时时间(在本例中为300秒)。 冬眠c3p0。idle_test_periods这是自动验证连接之前的中间时间(以秒为单位)
  2. # 2 楼答案

    我以前也找过类似的东西,但是在后端使用Oracle而不是MySQL。就我所见,在任何库中都没有实现这一点的机制,包括JDBC驱动程序。甚至你列出的超时,比如交易。setTimeout(),不要做你期望的事情。它们只需等待数据库语句完成执行,然后在超过给定超时时抛出TimeoutException。如果你有一个无限期挂起的查询,这是非常无用的。我发现的唯一一个现成的解决方案是在数据库本身上设置查询超时,在Oracle上这是一个全局设置,将影响对数据库的所有查询。这不是很有用。据我所知,要做你想做的事情,你必须启动一个单独的线程来计时查询,并在查询超时时以某种方式中断查询。我在Oracle或任何与数据库相关的库/框架中都找不到任何支持

  3. # 3 楼答案

    如果问题是前端响应性,可以考虑以最适合您的方式异步运行DB命中。那么你就不必为后端的及时性所累了。您可以使用JMS桥,或者如果您在Spring中,您可以使用@Async,或者任何其他异步的东西

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

    或者,您也可以将数据库移动到本地