Guice JPA - “This connection has been closed.” error

元气小坏坏 提交于 2019-12-04 12:32:25

A wild shot: The code here suggests, that the validationInterval is checked for testOnBorrow also.

Since you set this value from the 30sec default up to 5min this means that for 5 minutes after the DB drops the connection you still can get that stale connection. If your DB timeout is less than 5mins ... bad luck.

In order to test this theory you can set validationInterval to a ridiculous low value.

If that helps (reading: we have found the right knob) you should set it at least to a shorter time than the DB timeout. So when the DB decides to drop an idle connection the lower validationInterval will make sure that connection gets checked before the next borrow. Closed connections due to a DB server restart (i.e. without a timeout) will not be affected by this solution but at least the time returning to a sane state is lower too.

Note: I just asked Google for the code. I have no idea whether this is actual code or ancient code.

Actually I was right when I suspected an application error.

It's all nicely decribed in Issue 730: Automatically started UnitOfWork is never ended

When using the JpaPersistService, if you attempt to access an EntityManager outside of an active UnitOfWork, Guice will automatically start one for you. However, as Guice does not (and cannot) know when to end this UnitOfWork, it never does.

Result? The offending thread will be stuck with the same EntityManager throughout the life of the application. This is a bad state for the application to run in, and ours inevitably exhaust the available memory after a while and crash.

The real killer here is that it's not at all obvious when you've made this mistake. The only real tip-off is that you're getting inconsistent data from your database between different threads (due to the EMs first-level cache) or that the applications memory consumption keeps on growing. In my case it was the active connection in the pool that got me to suspect it, and then, when I turned on detailed logging I noticed that app was not borrowing the connection from pool at all, instead it was reusing the connection already held by unclosed EntityManager.

Actually there are quite some duplicates of this issue reported: http://code.google.com/p/google-guice/issues/list?can=1&q=UnitOfWork

If you have modified your META-INF/context.xml to include the validationQuery, Tomcat is likely to be caching the old definition under conf/engine/host/webapp.xml. Shut-down Tomcat, remove that file, and restart Tomcat. It wouldn't hurt to remove the work directory while Tomcat is down as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!