私のチームは、いくつかの変更を加え、古い Web アプリケーションを更新する必要があります。このアプリケーションには、1 つのメイン スレッドと、DB でデータを取得および挿入するためのワーカーとして使用される 5 ~ 15 のデーモン スレッドがあります。
これらのスレッドはすべてこの設計になっています (ここでは便宜上簡略化しています)。
public MyDaemon implements Runnable {
// initialization and some other stuffs
public void run() {
...
while(isEnabled) {
Engine.doTask1();
Engine.doTask2();
...
Thread.sleep(someTime);
}
}
}
Engine クラスは、DataAccessor クラスの他のメソッドを操作するために使用される一連の静的メソッドを提供します。これらのメソッドのいくつかは静的です。
public Engine {
public static doTask1() {
ThisDataAccessor.retrieve(DataType data);
// some complicated operations
ThisDataAccessor.insertOrUpdate(DataType data);
}
public static doTask2() {
ThatDataAccessor da = new ThatDataAccessor();
da.retrieve(DataType data);
// etc.
}
...
}
DataAccessor クラスは通常、同期されたメソッド (一部のクラスでは静的) で囲まれた単純な JDBC ステートメントを使用して DB と対話します。DataSource はサーバーで構成されます。
public ThatDataAccessor {
public synchronized void retrieve(DataType data) {
Connection conn = DataSource.getConnection();
// JDBC stuff
conn.close();
}
...
}
問題は、メイン スレッドが DB に接続する必要があり、これらのデーモン スレッドが動作しているときに、プールから利用可能な接続が簡単に不足し、「接続タイムアウトの待機」例外が発生することです。さらに、それらのデーモン スレッドでさえ、同じ例外を受け取ることがあります。
この問題を取り除かなければなりません。
20 接続で構成された接続プールがあり、「20」が本番環境の標準であるため、これ以上追加することはできません。「同期」キーワードを本当に必要な場所にのみ移動する予定であっても、コードの一部のブロックを同期する必要があります。しかし、それが実際に違いを生むとは思いません。
私たちはマルチスレッド プログラミングの経験がなく、この接続プーリングの問題にこれまで直面したことがありません。私たちが気づいていない欠陥はありますか?
スレッド クラスを 1 つずつプロファイリングしましたが、それらが並行して実行されていない限り、「接続タイムアウトを待っている」ことを正当化するボトルネックはないようです。アプリケーションは、Oracle 11g を使用して WebSphere 7 で実行されています。