1

在我看来,我们有一些代码尚未启动事务,用于只读操作,我们通过 JPA/Hibernate 和直接 SQL 的查询似乎可以工作。我们的框架会打开一个 hibernate/jpa 会话,但是对于遗留代码中的一些地方,我们发现没有打开任何事务。

似乎最终发生的事情是代码通常只要不使用 EntityManager.persist 和 EntityManager.merge 就可以运行。但是偶尔(可能是 1/10)次 servlet 容器会因此错误而失败...

Failed to load resource: the server responded with a status of 500 (org.hibernate.exception.JDBCConnectionException: The last packet successfully received from the server was 314,024,057 milliseconds ago.  The last packet sent successfully to the server was 314,024,057 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.) 

据我所知,我们的应用程序代码中只有少数几个在查询之前没有启动事务的地方会出现这个问题。有没有其他人认为可能是导致这种行为的非事务性查询运行?

仅供参考,这是我们的堆栈...

-Guice -Guice-Persist -Guice-Servlet -MySql 5.1.63 -Hibernate/C3P0 4.1.4.Final -Jetty

4

1 回答 1

0

是的,我认为。

如果不打开事务就开始查询,这个事务会被底层自动打开。此连接带有已打开的事务,将返回到连接池并提供给另一个用户,该用户将接收到已打开事务的连接,这可能导致状态不一致。

在我的公司,过去我们在只读非事务性查询方面遇到了很多问题,并调整了我们的框架来处理这个问题。除此之外,我们与 BoneCP 开发人员进行了交谈,他们同意开发一组功能来帮助处理这个问题,比如自动回滚返回池的未提交事务,并打印一个堆栈跟踪,说明哪个方法忘记提交事务。

这个问题在这里讨论过:http: //jolbox.com/forum/viewtopic.php ?f=3&t=98

于 2013-04-17T21:03:15.120 回答