私はこれを何時間も成功せずに行ってきました。マルチスレッドアプリケーションで DataSource をインスタンス化しています。すべてのスレッドは DataSource から接続を取得し、finally ブロックでそれらを閉じます (接続が確実に解放されるように、1 行ずつ行っています)。私が抱えている問題は、すべての接続で close メソッドが呼び出されても、DataSource によって解放されないことです。これは、DBCP データ ソースからsource.getNumActive()を出力する別のスレッドがあるためです。
これが基本的なセットアップです。
public class DataSourceHolder {
private static DataSource source;
static {
get the data source either from jndi or created from scratch
}
public DataSource getDataSource() { return source; }
}
すべてのボイラープレートコードをカプセル化するための単純な JdbcPattern (スプリング JdbcTemplate のようなものですが、非常に単純) があります。これは次のように定義されます。
public class JdbcPattern {
private DataSource source;
public JdbcPattern(DataSource source) {
this.source = source;
}
public int executeMethods(....) {
Connection c = source.getConnection();
try {
.. do the statements
} finally {
try { c.close(); } catch (SQLException ignore) { }
}
}
public List<?> queryMethods(....) {
}
}
最後に、プログラムの開始時に開始される 4 つのスレッドがあります。このスレッドはしばらくスリープ状態になり、ウェイクアップ時に DataSourceHolder プロバイダーの DataSource を使用して JdbcPattern をインスタンス化し、処理を開始します。作業が完了し、接続が閉じられると、DataSource によって実際には解放されません。DataSource の最大接続数に達すると、接続をインスタンス化できなくなるため、プログラムがフリーズします。
これをどう診断するか。
編集。これはTomcatで実行されています。一般的なメソッドはすべて catalina 共通ローダーによってロードされ、スレッドはいずれかの Web アプリケーション内で実行されます。クラスローダーの問題かもしれないと思っていました。