Java c3p0连接已过期

Java c3p0连接已过期,java,c3p0,guice-persist,Java,C3p0,Guice Persist,我使用的是C3P00.9.2.1、GWT2.6.0和SQLServer2012 我从c3p0得到一个断断续续的堆栈跟踪 [2015-Feb-03 16:30:12] - [INFO ] - A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@14bc0e [2015-Feb-03 16:30:12] - [INFO ] - Logging th

我使用的是C3P00.9.2.1、GWT2.6.0和SQLServer2012

我从c3p0得到一个断断续续的堆栈跟踪

[2015-Feb-03 16:30:12] - [INFO ] - A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@14bc0e
[2015-Feb-03 16:30:12] - [INFO ] - Logging the stack trace by which the overdue resource was checked-out.
java.lang.Exception: DEBUG STACK TRACE: Overdue resource check-out stack trace.
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:555)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
    at org.hibernate.c3p0.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:89)
    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:63)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:162)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:186)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:160)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1884)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1861)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
    at org.hibernate.loader.Loader.doQuery(Loader.java:909)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
    at org.hibernate.loader.Loader.doList(Loader.java:2551)
    at org.hibernate.loader.Loader.doList(Loader.java:2537)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2367)
    at org.hibernate.loader.Loader.list(Loader.java:2362)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1678)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
    at net.impro.portal.server.model.dao.CommsQueueDaoImpl.getOldestRecords(CommsQueueDaoImpl.java:54)
    at net.impro.portal.server.engine.uploader.AbstractBiometricUploader.getOldestRecords(AbstractBiometricUploader.java:217)
    at net.impro.portal.server.engine.uploader.UploaderMorpho$$EnhancerByGuice$$9212bdc2.getOldestRecords(<generated>)
    at net.impro.portal.server.engine.uploader.AbstractUploader.getSomeQueueData(AbstractUploader.java:222)
    at net.impro.portal.server.engine.uploader.UploaderMorpho$$EnhancerByGuice$$9212bdc2.getSomeQueueData(<generated>)
    at net.impro.portal.server.engine.uploader.AbstractBiometricUploader.processLoop(AbstractBiometricUploader.java:92)
    at net.impro.portal.server.engine.uploader.AbstractUploader.run(AbstractUploader.java:172)
    at java.lang.Thread.run(Unknown Source)
[2015-Feb-03 16:30:12]-[INFO]-签出的资源已过期,将被销毁:com.mchange.v2.c3p0.impl。NewPooledConnection@14bc0e
[2015-Feb-03 16:30:12]-[INFO]-记录用于签出过期资源的堆栈跟踪。
异常:调试堆栈跟踪:过期的资源签出堆栈跟踪。
位于com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:555)
在com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
在com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
位于com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
位于org.hibernate.c3p0.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:89)
位于org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.ActainConnection(AbstractSessionImpl.java:380)
位于org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.ActainConnection(LogicalConnectionImpl.java:228)
位于org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
位于org.hibernate.engine.jdbc.internal.statementpresparerimpl.connection(statementpresparerimpl.java:63)
位于org.hibernate.engine.jdbc.internal.StatementPrepareImpl$5.doPrepare(statementPrepareImpl.java:162)
位于org.hibernate.engine.jdbc.internal.StatementPrepareImpl$StatementPreparationTemplate.prepareStatement(statementPrepareImpl.java:186)
位于org.hibernate.engine.jdbc.internal.statementPrepareImpl.prepareQueryStatement(statementPrepareImpl.java:160)
位于org.hibernate.loader.loader.prepareQueryStatement(loader.java:1884)
位于org.hibernate.loader.loader.executeQueryStatement(loader.java:1861)
位于org.hibernate.loader.loader.executeQueryStatement(loader.java:1838)
位于org.hibernate.loader.loader.doQuery(loader.java:909)
在org.hibernate.loader.loader.doQueryAndInitializeNonLazyCollections(loader.java:354)上
位于org.hibernate.loader.loader.doList(loader.java:2551)
位于org.hibernate.loader.loader.doList(loader.java:2537)
位于org.hibernate.loader.loader.listIgnoreQueryCache(loader.java:2367)
位于org.hibernate.loader.loader.list(loader.java:2362)
位于org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
位于org.hibernate.internal.SessionImpl.list(SessionImpl.java:1678)
位于org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
位于net.impro.portal.server.model.dao.commsquedaoimpl.getOldestRecords(commsquedaoimpl.java:54)
位于net.impro.portal.server.engine.uploader.AbstractBiometricUploader.getOldestRecords(AbstractBiometricUploader.java:217)
在net.impro.portal.server.engine.uploader.UploaderMorpho$$EnhancerByGuice$$9212bdc2.getOldestRecords()上
位于net.impro.portal.server.engine.uploader.AbstractUploader.getSomeQueueData(AbstractUploader.java:222)
在net.impro.portal.server.engine.uploader.UploaderMorpho$$EnhancerByGuice$$9212bdc2.getSomeQueueData()中
位于net.impro.portal.server.engine.uploader.AbstractBiometricUploader.processLoop(AbstractBiometricUploader.java:92)
位于net.impro.portal.server.engine.uploader.AbstractUploader.run(AbstractUploader.java:172)
位于java.lang.Thread.run(未知源)
因此,它告诉我,我还没有在指定的超时时间内完成连接

<property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces" value="true" />
<property name="hibernate.c3p0.unreturnedConnectionTimeout" value="10" />

我不明白这怎么可能。我的代码很简单

@Transactional
 protected void getSomeQueueData() {
   logger.error("+Entered Thread " + Thread.currentThread());
   //A little clumsy here but I dont see anything wrong
   final CommsQueueDao commsQueueDao = InjectHelp.requestNewInstance(CommsQueueDao.class);
   List<CommsQueue> qData = getOldestRecords(commsQueueDao, MAX_LOCAL_QUEUE_SIZE);
   Iterator<CommsQueue> iterator = qData.iterator();
   //Iterate the result, pack it into a local queue
   //...         
   logger.error("-Exit Thread " + Thread.currentThread() + " " + stuffToSend.size());
 }

@Transactional
  protected List<CommsQueue> getOldestRecords(CommsQueueDao qDao, int fetchSize) {
  return qDao.getOldestRecords(getBioAddress(), fetchSize);
}


//FROM MY DAO CLASS
public List<CommsQueue> getOldestRecords(BioAddress bioAddress, int maxRecords) {
  Criteria cr = getSession().createCriteria(CommsQueue.class);
  cr.add(Restrictions.eq("bioAddress", bioAddress));
  cr.addOrder(Order.asc("id"));
  cr.setMaxResults(maxRecords);
  return cr.list();
}
@Transactional
受保护的void getSomeQueueData(){
logger.error(“+输入的线程”+线程.currentThread());
//这里有点笨拙,但我看不出有什么不对
final commsquedao commsquedao=InjectHelp.requestNewInstance(commsquedao.class);
List qData=getOldestRecords(commsquedao,最大本地队列大小);
迭代器迭代器=qData.Iterator();
//迭代结果,将其打包到本地队列中
//...         
logger.error(“-Exit Thread”+Thread.currentThread()+”+stuffToSend.size());
}
@交易的
受保护列表getOldestRecords(CommsQueueDao qDao,int fetchSize){
返回qDao.getOldestRecords(getBioAddress(),fetchSize);
}
//我的刀课
公共列表getOldestRecords(BioAddress BioAddress,int-maxRecords){
Criteria cr=getSession().createCriteria(commsquee.class);
cr.add(Restrictions.eq(“bioAddress”,bioAddress));
cr.addOrder(Order.asc(“id”));
cr.setMaxResults(maxRecords);
返回cr.list();
}
启动时,启动25个线程,每个线程调用getSomeQueueData()。大约有1/10次它失败了。我检查了调试输出,发现每个线程都像预期的那样在几秒钟内成功地进入和退出了该方法,那么为什么c3p0告诉我该连接仍在使用?只是澄清一下,@Transactional是guice,而不是spring

---编辑--- 我花了很多时间调查这个问题,结果变得更加令人费解

我还将c3p0更新为0.9.5

由于某种原因,@Transactional似乎不稳定。偶尔也不会有人给它打电话。我检查通过我的DAO的每个方法的堆栈跟踪,每隔一段时间,它表示已跳过拦截器处理

在我的DAO中,我有一个getSession()方法,当我添加一个100ms的任意睡眠时,几乎每个stackTrace都表明注释被跳过

此外,这些设置使问题几乎每次都发生

<property name="hibernate.c3p0.maxPoolSize" value="20" />
<property name="hibernate.c3p0.minPoolSize" value="1" />
<property name="hibernate.c3p0.numHelperThreads" value="1" />

…这些设置使问题很少发生

<property name="hibernate.c3p0.maxPoolSize" value="20" />
<property name="hibernate.c3p0.minPoolSize" value="20" />
<property name="hibernate.c3p0.numHelperThreads" value="20" />

就我的测试显示,完全删除c3p0似乎完全解决了这个问题

我已经读到,在反射