12

定期的に実行されるメインスレッドがあります。setAutoCommit(false) を使用して接続を開き、いくつかの子スレッドへの参照として渡されて、さまざまなデータベースの読み取り/書き込み操作を実行します。かなりの数の操作が子スレッドで実行されます。すべての子スレッドがデータベース操作を完了すると、メイン スレッドは開かれた接続でトランザクションをコミットします。ExecutorService 内でスレッドを実行していることに注意してください。私の質問は、スレッド間で接続を共有することをお勧めしますか? 「はい」の場合、以下のコードが正しく実装されているかどうかを確認してください。「いいえ」の場合、マルチスレッド シナリオでトランザクションを実行する他の方法は何ですか? コメント/アドバイス/新しいアイデアは大歓迎です。擬似コード...

Connection con = getPrimaryDatabaseConnection();
// let me decide whether to commit or rollback
con.setAutoCommit(false);

ExecutorService executorService = getExecutor();
// connection is sent as param to the class constructor/set-method
// the jobs uses the provided connection to do the db operation
Callable jobs[] = getJobs(con); 
List futures = new ArrayList();
// note: generics are not mentioned just to keep this simple
for(Callable job:jobs) {
    futures.add(executorService.submit(job));
}
executorService.shutdown();
// wait till the jobs complete
while (!executorService.isTerminated()) {
  ;
}

List result = ...;
for (Future future : futures) {
    try {
       results.add(future.get());
    } catch (InterruptedException e) {
      try {
        // a jobs has failed, we will rollback the transaction and throw exception
        connection.rollback();
        result  = null;
        throw SomeException();
      } catch(Exception e) {
       // exception
      } finally {
         try {
           connection.close();
         } catch(Exception e) {//nothing to do}
      }    
   }
}
// all the jobs completed successfully!
try {
  // some other checks
  connection.commit();
  return results;
} finally {
  try {
      connection.close();
  } catch(Exception e){//nothing to do}
}
4

3 に答える 3