Что мне делать с Java-программой, которая породила две части самого себя? - PullRequest
0 голосов
/ 08 марта 2010

У меня есть JAV-файл Java, который запускается заданием сервера SQL. Он успешно работает в течение нескольких месяцев. Процесс извлекает структурированный плоский файл в промежуточную базу данных, а затем помещает эти данные в файл XML.

Однако вчера процесс был запущен дважды одновременно. Я могу сказать из файла журнала, который создается, похоже, что процесс запускался дважды одновременно. Это вызвало много проблем, и файл XML, который он выгнал, был искажен и содержал дублирующиеся узлы и т. Д.

Мой вопрос заключается в том, является ли это известной проблемой с Java JVM, порождающей множество его экземпляров? Или я должен смотреть на сервер SQL как виновник? Я смотрю на «блокировку сокета» или блокировку файла, чтобы предотвратить несколько экземпляров в будущем.

Это первый экземпляр этой проблемы, о котором я когда-либо слышал.

Дополнительная информация:

Задание запускается каждую минуту. Задание запускает .bat-файл, содержащий java.exe - jar filename.jar

Запускается java-программа, сканирует каталог на наличие файла и затем выполняет цикл для обработки файла, если он его найдет. После обработки файла запускается еще один цикл, который выводит XML-сообщения.

Я могу предоставить примеры кода, если это поможет.

Спасибо,

Kevin

1 Ответ

3 голосов
/ 08 марта 2010

Это не проблема Java. Если вы хотите, чтобы приложение работало в одиночку, без копий, вы должны использовать сценарий оболочки или java-приложение, чтобы создать и снять блокировку где-нибудь.

Вы на самом деле запускаете несколько java, запуская более 1 пакетного задания с помощью одной и той же команды. Windows или Java могут теперь это не то, что вы хотите. Вы можете решить это следующим образом:

public static void main(String [ ] args)
{
   createLockIfNotExists();
   try {
       yourstuff;
   } finally {
     releaseLock();
   }
}
private static void createLockIfNotExists() throws MyLockAlreadyExists {
  // A bit tricky
  // check if LOCKFILE exists, if yes throw MyLockAlreadyExists
  // try to create LOCKFILE, can fail if at 1 ms earlier an other app created
  // that file, so an exception while creating also results in LockAlreadyExists
}

Есть ли где-нибудь хорошие примеры, которые обрабатывают эту блокировку? Может быть, в Apache Commons?

Здесь кажется работающим примером для Windows.

Вы также можете использовать базу данных для записи вашей блокировки. Конечно, заблокируйте таблицу блокировок перед ее использованием, чтобы никакие 2 процесса не записали свою блокировку одновременно, а затем прочитали запись блокировки, чтобы проверить, действительно ли вы получили блокировку. Что-то вроде псевдокода:

SELECT * FROM lock_table;

if locks.length > 0: someone else is running

LOCK lock_table;
INSERT INTO lock_table VALUES(my_pid);
UNLOCK lock_table;

SELECT pid FROM lock_table;

if pids.length > 1: what happened?
if pids[0] != my_pid: someone else got the lock 

Чуть больше сока, и вы также добавляете не только PID, но и временную метку и проверяете, устарела ли эта временная метка (слишком старая).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...