2015-02-03 4 views
0

나는 그것 내가 완료를 havent 말해, C3P0 0.9.2.1, GWT 2.6.0, SQLServer에 2012C3P0 연결 연체

내가

[2015-Feb-03 16:30:12] - [INFO ] - A checked-out resource is overdue, and will be destroyed: [email protected] 
[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) 

그래서 C3P0에서 간헐적 스택 트레이스를 얻고을 사용하고 있습니다 지정된 제한 시간 내에 연결 사용

<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(); 
} 

시작시, 25 스레드가 시작될 때마다 getSomeQueueData()를 호출합니다. 약 1/10 번 실패합니다. 디버그 출력을 확인하고 예상대로 모든 스레드가 성공적으로 2 초 이내에 메서드를 종료하고 종료했는지 확인합니다. 그래서 c3p0이 연결이 아직 사용 중임을 알리는 이유는 무엇입니까? 명확히하기 위해, @ 트랜잭션은 guice이지 봄이 아닙니다.

--- 편집 --- 나는이 문제를 조사하고 많은 시간을 보냈습니다 그리고 그것은 단지 더 수수께끼 ....

나는 또한 업데이트 한 C3P0 @Transactional

0.9.5로된다 어떤 이유로 엉뚱한 것 같습니다. 때때로 그것은 부르지 않는다. 내 DAO를 통과하는 모든 메소드의 스택 추적을 조사하며, 이는 흔히 인터셉터 처리가 건너 뛴다는 것을 나타냅니다. "

내 DAO에는 getSession() 메서드가 있으며 100ms의 임의의 수면을 추가하면 거의 모든 stackTrace가 주석을 건너 뛰었 음을 나타냅니다.

는 또한 이러한 설정은 문제가 매우 드물게

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

일이 그리고 모두 C3P0를 제거하면 완전히 문제를 해결할 것으로 보인다

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

... 이러한 설정은 문제를 만드는 거의 모든 시간이 일어날 수 있도록 내 테스트가 드러내는 한.

나는 마침내 guice에 의해 사용되는 반사가 그것을 피하기 위해 조심스럽게 사용 된 경우에주의해야 할 점이 있음을 읽었습니다. 나는 그 증상을 좁히기에는 너무 기괴하다. 때때로 guice가 제 수업을 올바르게 묶지 않는 것처럼 보일 때가 있습니다. 때로는 c3p0 오류처럼 보일 수도 있습니다.

오, com.google.inject.persist.Transactional을 사용하고 있는지 확인했습니다.

+0

어떤 시점에서 세션에서'close()'를 호출합니까? –

+0

이것은 Java 문제이며 GWT와 아무런 관련이 없습니다. 태그를 업데이트하여 불신을 구하십시오. – outellou

+0

Transactional이 세션 관리를 처리해야하므로 close()를 호출하지 않습니다. 나는 Transactional이 예상대로 행동하지 않는다면 그것이 GWT와 관련이있을 것이라고 생각했다. 나는 자바 태그를 추가 할 것이다. 감사. – user2046211

답변

0

문제를 해결하지 않고 다른 풀링 라이브러리를 사용해 본 결과, 종속성 주입에주의를 돌 렸습니다. 문제는 guice 관리 클래스의 생성자에있는 코드와 관련이 있다고 생각합니다. 해당 코드의 효과가 @Transactional로 표시된 메서드를 호출 할 가능성이있는 경우이 문제는 트랜잭션 주석이 "건너 뛴"경우 발생할 수 있습니다.

이것은 나에게 의미가있는 것처럼 보이므로, 나는 이것을 생성자에서 옮겼습니다. Im이 해결책이라고 확신하기 전에 나는 그것을 잠시 동안 계속 모니터링 할 것입니다.