2010-09-16 13 views
26

Używam C3P0 jako puli połączeń w Tomcat, i widzę bardzo niepokojące błędy:Pozorny zakleszczenie C3P0, gdy nici są puste?

2010-09-16 13:25:00,160 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com[email protected]43502400 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
2010-09-16 13:25:01,407 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com[email protected]43502400 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 10 
    Active Threads: 0 
    Active Tasks: 
    Pending Tasks: 
    com.mchange.[email protected]6e4151a7 
    Pool thread stack traces: 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6,5,main] 
    java.lang.Object.wait(Native Method) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534) 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main] 
    java.lang.Object.wait(Native Method) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534) 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main] 
    java.lang.Object.wait(Native Method) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534) 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main] 
    java.lang.Object.wait(Native Method) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534) 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5,5,main] 
    java.lang.Object.wait(Native Method) 
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534) 
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4,5,main] 
    java.lang.Object.wait(Native Method) 

... many more, exact same stack trace 

Linia 534 jest:

while (true) { 
    Runnable myTask; 
    synchronized (ThreadPoolAsynchronousRunner.this) { 
    while (!should_stop && pendingTasks.size() == 0) 
     ThreadPoolAsynchronousRunner.this.wait(POLL_FOR_STOP_INTERVAL); // <- here 
    if (should_stop) ... 

Wygląda to bardzo podobnie jak wszystkie wątki są bezczynny. Czekają na pracę. 0 aktywnych wątków i tylko 1 zadanie do wykonania. Jakieś wskazówki na temat tego, co się dzieje źle?

Oto konfiguracja:

ds.setUser(userName); 
ds.setPassword(password); 
ds.setMaxPoolSize(16); 
ds.setMaxConnectionAge(1800); 
ds.setAcquireRetryAttempts(4); 
ds.setMaxIdleTime(900); 
ds.setNumHelperThreads(10); 
ds.setCheckoutTimeout(1000); 
+0

Czy jesteś w stanie rozwiązać swój problem? (Wiem, że to było bardzo długo) – Ittai

+0

@Ittai: nie, ale w końcu odszedł. Nie ma pojęcia, co dokładnie to naprawiło :-( –

Odpowiedz

6

To brzmi jak już uzyskał połączenie z puli i nie wrócić na czas.

C3P0 określa "pozorne zakleszczenia", gdy połączenie zostanie uzyskane, ale nie zostanie zwrócone do puli w ramach limitu czasu wykrywania zakleszczenia.

Jeśli przeniesienie połączenia stanie się bliższe "akcji" i natychmiast po zakończeniu pracy z bazą danych zostanie zwrócone do puli, ten komunikat zniknie.

+2

Dokumentacja mówi, że setMaxAdministrativeTime domyślnie jest ustawione na 0 (tj. Na zawsze) .Ile dodatkowo, dlaczego powinienem/powinnam zwrócić połączenie do puli w jakimkolwiek ustalonym limicie czasu? Sprawdziłem to; Powinienem być mój tak długo, jak tego potrzebuję ... a nawet jeśli nie, to nie jest impasem! –

+1

Masz rację, dlatego OSTRZEŻENIE mówi o STANOWISKOWYM impasie, a przy okazji, korzystasz z puli połączeń, więc robisz nie musisz utrzymywać połączenia, gdy go nie używasz –

+1

Oczywiście, ale dane miejsce może być w długotrwałej transakcji, podczas której nie możesz go zwolnić –

0

miałem takie same (nie był w stanie wykryć) Problem rozwiązany poprawnie zamykania instancji oświadczenie i wynikowego (jakoś lewo niezamknięte):

String SQL = "SELECT 1"; 
try { 
    con = DriverManager.getConnection(host, userName, userPassword); 
    stmt = con.prepareStatement(SQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 
    try { 
     rs = stmt.executeQuery(SQL); 
     try { 
      rs.next(); 
      // ... 
     } finally { 
      rs.close(); 
     } 
    } finally { 
     stmt.close(); 
    } 
} catch (SQLException ex) { 
    Logger.getLogger(MyClass.class.getName()).log(Level.SEVERE, null, ex); 
} 
11

właśnie doświadczył podobnego problemu na bazie danych Oracle, ale w moim Liczba przypadków: Managed Thread i Active Thread była taka sama.

Managed Threads: 3 
    Active Threads: 3 

Dla mnie było to faktycznie błąd uwierzytelniania, ale pojawił się problem APPARENT DEADLOCK ze względu na sposób, w jaki robił inspekcję logowania.

2013-08-12 11:29:04,910 [Timer-4] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner: com[email protected]34996454 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
    2013-08-12 11:29:04,914 [Timer-4] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner: com[email protected]34996454 -- APPARENT DEADLOCK!!! Complete Status: 
      Managed Threads: 3 
      Active Threads: 3 
      Active Tasks: 
        [email protected]44 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) 
        [email protected]49 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) 
        [email protected]5 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 
      Pending Tasks: 
        [email protected]d7 
    Pool thread stack traces: 
      Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main] 
        java.net.SocketInputStream.socketRead0(Native Method) 
        java.net.SocketInputStream.read(SocketInputStream.java:150) 
        java.net.SocketInputStream.read(SocketInputStream.java:121) 
        oracle.net.ns.Packet.receive(Packet.java:300) 
        oracle.net.ns.DataPacket.receive(DataPacket.java:106) 
        oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:260) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:185) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:102) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) 
        oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) 
        oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) 
        oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760) 
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401) 
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) 
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) 
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) 
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521) 
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) 
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) 
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) 
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) 
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) 
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
      Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main] 
        java.net.SocketInputStream.socketRead0(Native Method) 
        java.net.SocketInputStream.read(SocketInputStream.java:150) 
        java.net.SocketInputStream.read(SocketInputStream.java:121) 
        oracle.net.ns.Packet.receive(Packet.java:300) 
        oracle.net.ns.DataPacket.receive(DataPacket.java:106) 
        oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:260) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:185) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:102) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) 
        oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) 
        oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) 
        oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760) 
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401) 
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) 
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) 
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) 
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521) 
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) 
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) 
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) 
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) 
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) 
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
      Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main] 
        java.net.SocketInputStream.socketRead0(Native Method) 
        java.net.SocketInputStream.read(SocketInputStream.java:150) 
        java.net.SocketInputStream.read(SocketInputStream.java:121) 
        oracle.net.ns.Packet.receive(Packet.java:300) 
        oracle.net.ns.DataPacket.receive(DataPacket.java:106) 
        oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:260) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:185) 
        oracle.net.ns.NetInputStream.read(NetInputStream.java:102) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124) 
        oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) 
        oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) 
        oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) 
        oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380) 
        oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760) 
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401) 
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) 
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) 
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) 
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521) 
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) 
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) 
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) 
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) 
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) 
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) 
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
+6

Co za kicker! Otrzymałem ten błąd po kilku poważnych zmianach w architekturze, więc pomyślałem, że go wkręciłem. Gdzie prawdziwy powód był związany z twoją odpowiedzią - ponieważ nie mogłem przejść przez zaporę ogniową do serwera bazy danych! – HankCa

+0

Miałem ten sam problem teraz. Znów ze względu na regułę firewalla. @HankCa dzięki za prowadzenie. –

+0

100% miejsce dla mnie, grupa bezpieczeństwa aws. – Gman

0

miałem ten sam problem ale przyczyną było trochę trudne do wykrycia, gdyż została spowodowana przez niektórych zasobów równoczesnych prób uzyskania połączenia w tym samym czasie.

Ponieważ można odczytać, czy pula nie została zainicjalizowana, należy podać kod inicjujący, wywołując funkcję konfiguracji.

public Connection getConnection() throws SQLException { 
    if (mCPDS == null) { 
     setupPool(); 
    } 

    return mCPDS.getConnection(); 
} 

Problem polegał na tym, że wiele środków staraliśmy się pozyskać połączenie na początku programu, tak więcej niż jeden były instancji basen przyczyną problemu po jakimś czasie.

Rozwiązaniem było zadeklarowanie metody zsynchronizowanej w celu uniknięcia innych zasobów, gdy metoda została wywołana i nadal znajduje się w instancji puli na przykład.

public synchronized Connection getConnection() throws SQLException { 
    if (mCPDS == null) { 
     setupPool(); 
    } 

    return mCPDS.getConnection(); 
} 

Może to być błąd projektowy polegający na niestosowaniu singletonu, ale rozwiązuje problem braku wydajności.

-1

Wpadliśmy na ten problem i rozwiązać go przez dodanie tego do config C3P0:

<property name="statementCacheNumDeferredCloseThreads" value="1"/> 

wg: this from the C3P0 doc

-1

Podobny problem wystąpił na serwerze glassfish4 podczas wdrażania aplikacji. Okazało się, że był to problem z konfiguracją bazy danych. Upewnij się, że konfiguracje połączeń z bazą danych są poprawne, sprawdź, czy nazwa hosta podana w konfiguracji umożliwia połączenie z bazą danych. Spróbuj połączyć się z bazą danych ręcznie za pomocą skonfigurowanej nazwy użytkownika i nazwy hosta/domeny. W razie potrzeby zezwól użytkownikowi bazy danych na połączenie się z wymaganą domeną. Przebuduj aplikację, stosując poprawne konfiguracje bazy danych, a następnie wdróż ją.

0

Witam przyjacielu tylko po to, aby skomentować, miałem ten sam przypadek. Właśnie skonfigurowałem mój projekt zaćmienia wiosna-hibernacja i pokazałem ten sam wyjątek, należy zauważyć, że mój projekt wciąż nie ma żadnego zapytania.

Postanowiłem, że problem z poniższych kroków:

1) Czysty projektu: Project -> Clean ... 2) tworzenie projektu: Project -> Build Project

Mam nadzieję, że pracuje dla ty.