views:

30

answers:

0

Hi,

I have an environment with 4 servers and 2 oracle database servers which have streams between them for instant 2 way replication.

I have a servlet (I cannot control which of the 4 servers it goes to) which checks if a job is running and if not it starts the job in a thread. Only one of these jobs should be running at any time. I am placing a flag on the database to indicate that the job is running (as there are 4 servers I cannot just hold the flag in memory).

In a synchronized block I do a check to see if the job is running and if its not I set a flag. After this I start the job

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

This works for an environment where there is only one server, but not in my scenario.

If I have a thread on 2 different servers in the synchronized block and they are both after checking that the job isn't running then they will both try to set the flag. So I have built in contingency to be able to catch a unique key constraint (each job has an id, which is the primary key in the database. I have this value hard coded to 1 so that only one entry can be in database). I am using 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.");
   }

So again, this function correctly but I can imagine there is a better way to do this. Can you please suggest another approach? It seems to me that I need something which will lock the database (while I check if flag is running and then set flag running). Remember, there are 2 databases, so I don't know if having the lock on just one will work. Should I be looking at Spring's tranactions? Or can you suggest something else?

Thanks.