3

マルチスレッド環境でデータベース接続プールを処理するためにc3p0を使用しています。質問は他のプーリングライブラリに関係するかもしれませんが、これは私が持っているものです.

最近、直接的または間接的に c3p0 を使用して、そのようなスレッドに割り込み処理を実装する必要がありました。がプールからを取得しようとしているinterrupt()ときに が呼び出されると、 がスローされることに気付きました。c3p0Datasource.getConnection()ConnectionInterruptedException

明らかに、これはwait()

at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1414)

涼しい。問題は、これを適切に処理する方法です。どちらも、a) スレッドが終了する前にトランザクションを続行したい場合と、b) 中止したい場合です。

うまく機能しているように見える解決策を試しました(回答として投稿)-実際、この件は閉じられていると思います。それ以外の場合は、お気軽に参加してください。ありがとう!

4

1 に答える 1

3

1 秒以内に多くのConnectionリクエストを起動し、プールのボトルネックを確認するたびに SELECT を実行してから、interrupt().

私が見つけたのは、スタックトレースが c3p0 でのメルトダウンを示していても、connectionオブジェクトがキャッチされた後は問題なくダンディであるということでした。まさに今、私は彼らのソースをチェックしています。確かに、彼らは. 彼らは適切な警告さえ投げます:InterruptedExceptionawaitAvailable(..)InterruptedException

WARNING: com.mchange.v2.resourcepool.BasicResourcePool@5bcf4b61 -- an attempt to checkout a resource was interrupted, and the pool is still live: some other thread must have either interrupted the Thread attempting checkout!

多くのあいまいな言葉の合間にはありますが、まだ生きていると言っています。解決しました。

とにかくここでテストです。

ComboPooledDataSource ds = new ComboPooledDataSource();

// testing with various pool sizes - same effect
ds.setMinPoolSize(1);
ds.setMaxPoolSize(5);
ds.setInitialPoolSize(2);

Thread connectingThread = new Thread() {

    public void run() {
        Connection cnxn = null;
        while (true) {
            try {
                cnxn = ds.getConnection();
                System.out.println("Got connection.);
                executeQuery(cnxn);
            } catch (SQLException e) {
                System.out.println("Got exception.");
                e.printStackTrace();

                // SOLUTION:
                Throwable cause = e.getCause();
                if (cause instanceof InterruptedException) {
                    System.out.println("Caught InterruptedException! Cnxn is " + cnxn);

                    // note that cnxn is a com.mchange.v2.c3p0.impl.NewProxyConnection
                    // also note that it's perfectly healthy.
                    //
                    // You may either want to:
                    // a) use the cnxn to submit your the query

                    executeQuery(cnxn);
                    cnxn.close()

                    // b) handle a proper shutdown

                    cnxn.close();

                }
                break;
            }
        }
    };
};

connectingThread.start();

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {          e.printStackTrace();        }

connectingThread.interrupt();
于 2014-09-20T19:12:19.427 に答える