私は一定の間隔でデータベースにクエリを行うプログラムを持っており、呼び出したレコードで何らかのアクションを実行してからテーブルを再度更新します。JDBCとスレッディング
ExecutorServiceを使用してスレッドを実行していますが、各スレッドが(データベースを更新する必要があるため)独自の接続を取得する必要がありますか、初期の結果を照会するのに使用した接続と同じ接続を使用できますか?
接続プーリングの作業は、Oracle 9iで可能です。
私は一定の間隔でデータベースにクエリを行うプログラムを持っており、呼び出したレコードで何らかのアクションを実行してからテーブルを再度更新します。JDBCとスレッディング
ExecutorServiceを使用してスレッドを実行していますが、各スレッドが(データベースを更新する必要があるため)独自の接続を取得する必要がありますか、初期の結果を照会するのに使用した接続と同じ接続を使用できますか?
接続プーリングの作業は、Oracle 9iで可能です。
この方法でドライバがスレッドセーフではないため、別々のスレッドには常に別の接続を使用する必要があります。接続プールは安全な方法で接続の再利用を可能にするので、あなたを助けることができます。
あなたが問題を正しく理解していれば、あるスレッドがクエリを担当し、データベースを更新する可能性のあるN個のスレッドを開始するクエリディスパッチパターンを実行することもできます。
スレッドは次の構造使用して、行とテーブルのロックの面で互いにつまずくはありませんので、あなたはまた、PreparedStatementのを経由してバッチ更新を行うことを検討可能性があります
。
編集てpstmtとバッチ更新を行う方法について
例:
PreparedStatement pstmt = connection.prepareStatement(
"UPDATE table SET field=? WHERE id=?");
for (int i = 0; i < 100; i++) {
pstmt.setInt(1, i * i);
pstmt.setInt(2, i);
pstmt.addBatch();
}
pstmt.executeBatch();
pstmt.close();
それとも、更新要求が処理スレッドから到着ループでのキューを照会できます。
class WhatToUpdate {
public int id;
public int value;
}
Queue<WhatToUpdate> queue = new LinkedBlockingQueue<WhatToUpdate>();
PreparedStatement pstmt = connection.prepareStatement(
"UPDATE table SET field=? WHERE id=?");
int poisons = THE_NUMBER_OF_PROCESSING_THREADS;
while (true) {
WhatToUpdate record == queue.take();
if (record == null) { // poison pill
if (--poisons <= 0) {
break;
}
}
pstmt.setInt(1, record.value);
pstmt.setInt(2, record.id);
pstmt.addBatch();
}
pstmt.executeBatch();
pstmt.close();
Oracle jdbc OracleConnection
およびOraclePreparedStatement
のコードを見ると、m重要なメソッドの中で同期されているので、スレッドセーフです。 1つのConnection
を複数のスレッドに渡って使用しても、それぞれのスレッドは、独自のアクションを実行する前に、Connection
およびPreparedStatement
(特に)の操作を完了するまで待機する必要があるため、
@akf:質問にはOracle 9iが特に言及されていますが、実装固有の動作に依存することはお勧めできません。確かに、他のベンダーのJDBCスタックがスレッドセーフであるという保証はありません。 AFAIKでは、JDBC仕様では必須ではありません。 –
@Stephen C、良い点。 – akf
PreparedStatement APIスレッドを安全にすることはできません。すべてのメソッドを同期させることでスレッドを安全にすることはできません。これはステートフルなAPIです。一般にPreparedStatementインスタンスにスレッド間で安全にアクセスできるようにするには、APIを再設計する必要があります。 –
ありがとうございます! 私は処理のために1つのクエリスレッドとN個のスレッドを持っています。準備されたステートメントを使用してバッチ更新を行うにはどうすればよいですか? – Ngetha
ありがとう、これは完全に私のために働いた – Ngetha
@ Ngetha:これはあなたの質問に答えた場合は、*受け入れる*答え:http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work(他の質問にも同じことが起こります。) –