我在我的一个生产环境中面临这个问题。它经常发生但并不总是在应用程序的同一部分发生,它非常随机。
部署在此环境中的应用程序与部署在不同机器上的其他应用程序非常相似,它们使用相同的技术和关闭设置,但错误仅发生在此环境中,因此很难找出问题所在。
我必须说这些错误最近开始出现,因为有几个更新更改:
应用程序从 Windows 迁移到 Linux
PostgresSQL 8.2 到 9.2
雄猫 5 到 雄猫 6
所有这些更改也已在其他未遇到任何问题的已部署应用程序上完成。
应用程序使用的技术是:
休眠 2.1.6
PostgreSQL 9.2
雄猫 6.0.35
context.xml 中的配置是:
<Resource name="jdbc/psa" auth="Container" type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/psa?compatible=7.4"
username="xxx" password="xxx" maxActive="100" maxIdle="30"
maxWait="10000" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
defaultAutoCommit="false" removeAbandoned="true"
removeAbandonedTimeout="60" logAbandoned="true" validationQuery="select 1"
testOnBorrow="true" testOnReturn="true" testWhileIdle="true"
timeBetweenEvictionRunsMillis="300000"/>
请注意,驱逐是活跃的,只是试图解决问题,但没有结果。
接下来是一个典型问题的流程:
1.- 打开一个新的 Hibernate 会话
2.- 我在查询之前检查此会话是否已打开并连接
3.-在日志上看到打开的会话有效后,产生了异常
- 添加
其中一个错误的完整堆栈跟踪如下:
29 03 2013 10:00:00 INFO EasyApScheduler_Worker-8 com.psa.accounting.eureca.logic.EurecaNLAccountingLogic - -- Process EURECA_NL starts
29 03 2013 10:00:00 INFO EasyApScheduler_Worker-2 com.psa.accounting.eureca.logic.EurecaSCAccountingLogic - -- Process EURECA_SC starts
29 03 2013 10:00:00 DEBUG EasyApScheduler_Worker-2 com.xeridia.persistence.ServiceLocator - Session opened: net.sf.hibernate.impl.SessionImpl@22880d66. Opened: true, Connected: true
29 03 2013 10:00:00 DEBUG EasyApScheduler_Worker-2 com.xeridia.persistence.ServiceLocator - [getConnection]|16|Thread[EasyApScheduler_Worker-2,4,main]|
29 03 2013 10:00:00 DEBUG EasyApScheduler_Worker-2 com.xeridia.persistence.ServiceLocator - [getConnection]|16|Thread[EasyApScheduler_Worker-2,4,main]|com.easyap.invoice.persistence.InvoiceDAOHibernate.<init>(InvoiceDAOHibernate.java:364)
29 03 2013 10:00:00 ERROR EasyApScheduler_Worker-8 net.sf.hibernate.util.JDBCExceptionReporter - Connection org.postgresql.jdbc3g.Jdbc3gConnection@1b0ca3f7 is closed.
29 03 2013 10:00:00 DEBUG EasyApScheduler_Worker-2 com.xeridia.persistence.ServiceLocator - [getConnection]|16|Thread[EasyApScheduler_Worker-2,4,main]|com.psa.invoice.persistence.PSAInvoiceDAOHibernate.<init>(PSAInvoiceDAOHibernate.java:52)
29 03 2013 10:00:00 ERROR EasyApScheduler_Worker-8 net.sf.hibernate.util.JDBCExceptionReporter - Connection org.postgresql.jdbc3g.Jdbc3gConnection@1b0ca3f7 is closed.
29 03 2013 10:00:00 ERROR EasyApScheduler_Worker-8 net.sf.hibernate.util.JDBCExceptionReporter - Could not execute query
java.sql.SQLException: Connection org.postgresql.jdbc3g.Jdbc3gConnection@1b0ca3f7 is closed.
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.checkOpen(DelegatingConnection.java:398)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:279)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
at net.sf.hibernate.impl.BatcherImpl.getPreparedStatement(BatcherImpl.java:257)
at net.sf.hibernate.impl.BatcherImpl.getPreparedStatement(BatcherImpl.java:232)
at net.sf.hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:65)
at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:779)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:265)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.doList(Loader.java:1033)
at net.sf.hibernate.loader.Loader.list(Loader.java:1024)
at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:854)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1544)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
at com.xeridia.persistence.BaseDAOHibernate.findByQuery(BaseDAOHibernate.java:312)
at com.xeridia.persistence.BaseDAOHibernate.findByQuery(BaseDAOHibernate.java:291)
at com.psa.invoice.persistence.PSAInvoiceDAOHibernate.getAccountingInvoicesWithNoProblem(PSAInvoiceDAOHibernate.java:215)
at com.psa.accounting.eureca.logic.EurecaNLAccountingLogic.getAccountingDataFromDB(EurecaNLAccountingLogic.java:469)
at com.psa.accounting.eureca.logic.EurecaNLAccountingLogic.process(EurecaNLAccountingLogic.java:207)
at com.psa.accounting.eureca.scheduler.CronEurecaNLAccounting.execute(CronEurecaNLAccounting.java:91)
at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
管理所有 Hibernate 会话的类是一个名为 ServiceLocator 的类。此类的方法 getConnection() 返回一个新连接,其代码如下:
synchronized (session) {
s = (Session) session.get();
if ((s == null)||(!s.isOpen())) {
s = null;
s = getSessionFactory().openSession();
if (s != null) {
log.debug("Session opened: " + s + ". Opened: " + s.isOpen() +
", Connected: " + s.isConnected());
printThreadDataForClosedConnections("[getConnection]");
}
session.set(s);
}
if (!s.isConnected()) {
s.reconnect();
log.debug("Session reconnected: " + s + ". Opened: " + s.isOpen() +
", Connected: " + s.isConnected());
printThreadDataForClosedConnections("[getConnection]");
}
}
对象“会话”声明为:
public static final ThreadLocal session = new ThreadLocal();
为不同的线程获取不同的会话,因此关闭线程之间的会话不应该存在问题。
您在上面的堆栈跟踪中可以看到,EasyApScheduler_Worker-2 获得了一个新连接,if ((s == null)||(!s.isOpen())) {
但 EasyApScheduler_Worker-8 没有,这意味着它的“会话”对象存在并且打开或无法获得连接,对应于第一个错误的踪迹29 03 2013 10:00:00 ERROR EasyApScheduler_Worker-8 net.sf.hibernate.util.JDBCExceptionReporter - Connection org.postgresql.jdbc3g.Jdbc3gConnection@1b0ca3f7 is closed.
我不知道问题是来自 Hibernate、Postgres 还是 Tomcat。我在谷歌上几乎没有发现这个错误,所以我希望你能帮帮我。
请询问您需要的任何额外信息或设置以提供帮助。
提前致谢。