У меня есть среда с 4 серверами и 2 серверами баз данных Oracle, между которыми есть потоки для мгновенной 2-сторонней репликации.
У меня есть сервлет (я не могу контролировать, к какому из 4 серверов он идет), который проверяет, выполняется ли задание, и если нет, запускает задание в потоке. Только одно из этих заданий должно выполняться в любое время. Я помещаю флаг в базу данных, чтобы указать, что задание выполняется (так как есть 4 сервера, я не могу просто держать флаг в памяти).
В синхронизированном блоке я проверяю, выполняется ли задание, и если нет, я устанавливаю флаг. После этого я начинаю работу
synchronized (this)
{
if (statusDao.isJobRunning())
{
throw new JobRunningException("Job is already running");
}
//set flag to indicate that job is running
statusDao.setJobRunningFlag();
}
Это работает для среды, где есть только один сервер, но не в моем сценарии.
Если у меня есть поток на 2 разных серверах в синхронизированном блоке, и они оба после проверки, что задание не выполняется, они оба попытаются установить флаг. Поэтому я создал непредвиденные обстоятельства, чтобы иметь возможность перехватить ограничение уникального ключа (каждое задание имеет идентификатор, который является первичным ключом в базе данных. У меня это значение жестко задано равным 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.");
}
Итак, еще раз, эта функция работает правильно, но я могу представить, что есть лучший способ сделать это. Можете ли вы предложить другой подход? Мне кажется, что мне нужно что-то, что заблокирует базу данных (пока я проверяю, запущен ли флаг, а затем устанавливаю флаг работающим). Помните, что есть две базы данных, поэтому я не знаю, сработает ли блокировка только на одной. Должен ли я смотреть на весенние сделки? Или вы можете предложить что-то еще?
Спасибо.