web-dev-qa-db-ja.com

スレッドがすべて空の場合のC3P0の明らかなデッドロック?

Tomcatの接続プールとしてC3P0を使用していますが、非常に心配なエラーが表示されます。

2010-09-16 13:25:00,160 [Timer-0] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@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.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Complete Status:
  Managed Threads: 10
  Active Threads: 0
  Active Tasks:
  Pending Tasks:
    com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@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);
28

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.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@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.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@34996454 -- APPARENT DEADLOCK!!! Complete Status: 
            Managed Threads: 3
            Active Threads: 3
            Active Tasks: 
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@6730b844 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@2f91ad49 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@507ac05 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
            Pending Tasks: 
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@3aae7ed7
    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)
14
eebbesen

これは、プールから既に接続を取得しており、時間内に接続を戻さないように聞こえます。

接続が取得されたが、デッドロック検出タイムアウト内にプールに戻されなかった場合、C3P0は「見かけのデッドロック」を決定します。

接続の取得を「アクション」の近くに移動し、データベースの作業が完了した直後にプールに戻すと、このメッセージは消えます。

7
Thomas Weber

これはあなたの問題を整理します

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+c3p

完了したら、忘れずに声明を閉じてください!!

4
ChristiaanP

回答に関する私のコメント https://stackoverflow.com/a/18192588/1019307 は、回答である必要があることを示唆する十分な賛成票を受け取りました。

データベースサーバーにファイアウォールを通過できなかったため、このエラーを受け取りました。それが問題かどうかを確認してください。

2
HankCa

@eebbesen、あなたと同じエラーが出ました。 Tomcatバージョン9.0.6を実行しています。 Mavenプロジェクトにhibernate core ver 5.2.10、hibernate c3p0 ver 3.6.3があります。私は認証エラーではなく、以前にコンピューターの名前を変更したことが原因でした。これはTomcatにすぐには影響しませんでしたが、マシンの再起動時に、Eclipse(Oxygen 2)を介してTomcatを再起動しようとしたときに、発生した問題のためにEclipseを起動できなくなりました。

私はこれをグーグルで検索し、このリンクを見つけました。

https://community.Oracle.com/thread/339825

それが言うところ:

まず、OracleServiceXEおよびOracleXETNSListenerサービスが実行されているかどうかを確認します。 URLの127.0.0.1をマシンのIPまたは名前に置き換えます。 tnsnames.oraファイルで宣言されているホストと一致する必要があります。

後に、このtnsnames.oraファイルの場所について言及しましたが、私にとってはここにありました。

C:\oraclexe\app\Oracle\product\11.2.0\server\network\ADMIN

このtnsnames.oraファイルを見て、私はこれを見ました:

XE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(Host = MyMachineName-7)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

しかし、最近、マシンの名前をMyMachineName-5に変更しました。 7を5に変更して、ファイルを保存しました。このディレクトリ内の「listener.ora」ファイルを確認しましたが、同じ問題がありました。

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
      (ADDRESS = (PROTOCOL = TCP)(Host = MyMachineName-7)(PORT = 1521))
    )
  )

7を5に変更して、ファイルを保存しました。

次に、タスクマネージャーを開き、[サービス]タブをクリックして、[Oracle]サービスを確認しました。 OracleXETNSListener、OracleXEClrAgent、OracleServiceXEで再起動しました。 EclipseでTomcatを再起動しましたが、今回は問題が発生しました。

付録:

私もこれをグーグルで検索しました:

https://community.Oracle.com/thread/2267906

これは私を試してみることにつながりました:

1)Windows Defenderでファイアウォールをオフにしました(mcaffeeファイアウォールは既にオフになっています)

2)休止状態ファイルhibernate.cfg.xmlで使用していた資格情報でログインできることを確認するためにsqlplusを開始しました

C:\ oraclexe\app\Oracle\product\11.2.0\server\bin\sqlplus.exe

3)Oracle Database 11gへのデスクトップショートカットを開始しました

ただし、マシン名の問題を修正した後でも、これは失敗しました。

4)dbVisualizerを使用して、Oracleへの接続を試みました。これは、.oraファイルマシン名の問題を解決した後にのみ機能しました。接続をダブルクリックし、[pingサーバー]ボタンをクリックします。

1
Steve T

こんにちは私の友人はコメントするために、私は同じケースを持っていました。 Spring-Hibernate Eclipseプロジェクトを構成したところ、同じ例外が表示されました。プロジェクトにはまだクエリがないことに注意してください。

以下の手順で問題を解決しました。

1)プロジェクトのクリーン:プロジェクト->クリーン... 2)プロジェクトのビルド:プロジェクト->プロジェクトのビルド

私はそれがあなたのために働くことを望みます。

ステートメントと結果セットのインスタンスを正しく閉じることで解決した同じ問題(検出できなかった)がありました(どういうわけか閉じられていません):

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

私は同じ問題を抱えていましたが、同時に接続を取得しようとするいくつかの同時リソースが原因であるため、原因を見つけるのは少し困難でした。

プールが初期化されていない場合は、セットアップ関数を呼び出してプールを初期化するために提供されたコードを読むことができます。

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

これは、シングルトンを使用しないための設計エラーである可能性がありますが、パフォーマンスが不足している問題を修正します。

0
atzu

私はちょうど同じ問題を突然抱えました:デッドロックはアプリケーションをデバッグモードで起動するときにのみ存在し(IntelliJを使用している)、通常の実行で実行しているときに問題がなかったことに気づいた後、それを掘り始めました。

最後に、ブレークポイントが接続をブロックしていることがわかりました。Intellijがアプリケーションがそのブレークポイントを通過していることを「リッスン」しなかったが、ブレークポイントの原因のどこかでハングし、これが原因でした適切なデッドロック

プロジェクト内のすべてのブレークポイントを削除した後、すべてが再びスムーズに開始されました。

これが誰かを助けることを願って

0
Leviand