Подтвердить что ты не робот

C3P0 кажущийся тупик, когда потоки все пусты?

Я использую C3P0 в качестве пула соединений в Tomcat, и я вижу очень тревожные ошибки:

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

Линия 534:

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

Он очень похож, что все потоки простаивают. Они ждут работы. 0 активных потоков, и только 1 задача для завершения. Любые подсказки о том, что происходит не так?

Здесь конфигурация:

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

Ответ 1

Я просто столкнулся с аналогичной проблемой с базой данных Oracle, но в моем случае Managed Thread и Active Thread подсчеты были одинаковыми.

    Managed Threads: 3
    Active Threads: 3

Для меня это была ошибка аутентификации, но появилась как ошибка APPARENT DEADLOCK из-за того, как я выполнял аудит входа в систему.

    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)

Ответ 2

Это похоже на то, что вы уже получили соединение из пула и не возвращаете его вовремя.

C3P0 определяет "кажущиеся взаимоблокировки" при получении соединения, но не возвращается в пул в тайм-аут обнаружения блокировки.

Если вы переместите соединение на более близкое к "действию" и сразу же вернете его в пул после завершения работы с базой данных, это сообщение исчезнет.

Ответ 3

Это позволит решить вашу проблему.

ds.setMaxStatements(1000);
ds.setMaxStatementsPerConnection(100); (the maximum number of prepared statments your system can execute on a single connection)

проверить: https://forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0

Не забудьте закрыть свои заявления после того, как вы закончите с ними!

Ответ 4

У меня была такая же проблема (не удалось обнаружить), которая была решена путем правильного закрытия экземпляров Statement и Resultset (как-то осталось незакрытым):

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

Ответ 5

У меня была такая же проблема, но причина была немного сложной, поскольку это было вызвано одновременными ресурсами, которые пытались получить соединение одновременно.

Как вы можете прочитать, если пул не был инициализирован кодом, предоставленным для его инициализации, вызвав функцию настройки.

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

    return mCPDS.getConnection();
}

Проблема заключалась в том, что многие ресурсы пытались получить соединение в начале программы, поэтому более одного экземпляра создавали пул, вызывающий вашу проблему через некоторое время.

Решение состояло в том, чтобы объявить синхронизированный метод, чтобы не использовать другие ресурсы, пока вы вызывали этот метод, и он все еще используется для создания экземпляра пула, например.

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

    return mCPDS.getConnection();
}

Это может быть ошибка дизайна для не использования синглета, но устраняет проблему, которая не обладает некоторой производительностью.

Ответ 6

Мы столкнулись с этой проблемой и решили ее, добавив это в конфигурацию C3P0:

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

в соответствии с: это из документа C3P0

Ответ 7

Аналогичная проблема возникла на сервере glassfish4 при развертывании приложения. Оказалось, что это проблема с конфигурацией базы данных. Просто убедитесь, что конфигурации подключения к базе данных правильны, убедитесь, что имя хоста, указанное в конфигурации, позволяет подключиться к базе данных. Попробуйте подключиться к базе данных вручную с настроенным именем пользователя и именем/доменом. Если необходимо, разрешите пользователю db подключиться из требуемого домена. Переустановите приложение с правильными настройками db и затем разверните его.