1

私は、4 台のサーバーと 2 台の Oracle データベース サーバーを備えた環境を持っており、それらの間にストリームがあり、双方向のインスタント レプリケーションが可能です。

ジョブが実行されているかどうかをチェックし、そうでない場合はスレッドでジョブを開始するサーブレットがあります (4 つのサーバーのどれに行くかを制御できません)。これらのジョブのうち、一度に実行できるのは 1 つのみです。ジョブが実行中であることを示すフラグをデータベースに設定しています (サーバーが 4 つあるため、フラグをメモリに保持することはできません)。

同期ブロックでは、ジョブが実行されているかどうかを確認し、実行されていない場合はフラグを設定します。この後、私は仕事を始めます

synchronized (this)
{ 
 if (statusDao.isJobRunning())
 {
  throw new JobRunningException("Job is already running");
 }
 //set flag to indicate that job is running
 statusDao.setJobRunningFlag();
}

これは、サーバーが 1 つしかない環境では機能しますが、私のシナリオでは機能しません。

同期ブロック内の 2 つの異なるサーバーにスレッドがあり、両方ともジョブが実行されていないことを確認した後である場合、両方ともフラグを設定しようとします。そのため、一意のキー制約をキャッチできるように不測の事態を組み込みました (各ジョブには、データベースの主キーである ID があります。この値を 1 にハードコードして、データベースに 1 つのエントリのみを含めることができるようにしています)。Springs JdbcTemplate を使用しています

 try {
      this.jobJdbcTemplate.update(insert into JOB (JOB_ID, RUNNING) values ('1','Y'));
   }catch (DataAccessException dae){
     if (StringUtils.contains(dae.getMessage(), "ORA-00001"))
     {
      throw new JobRunningException("Job is already running");
     }   
     throw new JobException("Error setting Job Flag.");
   }

繰り返しますが、これは正しく機能しますが、これを行うためのより良い方法があると想像できます。別のアプローチを提案できますか?データベースをロックする何かが必要なようです(フラグが実行されているかどうかを確認してから、フラグを実行中に設定します)。2 つのデータベースがあることを思い出してください。1 つだけをロックしても機能するかどうかはわかりません。Spring のトランザクションを確認する必要がありますか? それとも何か他のことを提案できますか?

ありがとう。

4

0 に答える 0