Как сохранить историю заданий с помощью планировщика Quartz - PullRequest
9 голосов
/ 02 июня 2010

Я бы хотел сохранить историю заданий, которые были запланированы планировщиком Quartz и содержащим следующие свойства: «время начала», «время окончания», «успех», «ошибка».

Для этого есть два интерфейса: ITriggerListener и IJobListener (я использую соглашение об именах C # для интерфейсов, потому что я использую Quartz.NET, но тот же вопрос можно задать для версии Java).

IJobListener имеет метод JobToBeExecuted и JobWasExecuted. Последний обеспечивает JobExecutionException, чтобы вы знали, когда что-то пошло не так. Тем не менее, нет никакого способа сопоставить JobToBeExecuted и JobWasExecuted. Предположим, моя работа длится десять минут. Я начинаю его с t0 и t0+2 (поэтому они перекрываются). Я получаю два звонка на JobToBeExecuted и вставляю два раза в мою таблицу истории. Когда оба задания заканчиваются на t1 и t1+2, я получаю два звонка на JobWasExecuted. Как узнать, какую запись базы данных обновлять при каждом вызове (чтобы сохранить время окончания с соответствующим временем начала)?

ITriggerListener имеет еще одну проблему. Нет способа получить какие-либо ошибки в методе TriggerComplete, когда задание не выполнено.

Как мне получить желаемое поведение?

Ответы [ 3 ]

12 голосов
/ 03 июня 2010

Способ сделать это - сгенерировать идентификатор в JobToBeExecuted, сохранить его в JobExecutionContext и извлечь его снова из JobExecutionContext в JobWasExecuted.

public void JobToBeExecuted(JobExecutionContext context)
{
    // Insert history record and retrieve primary key of inserted record.
    long historyId = InsertHistoryRecord(...);
    context.Put("HistoryIdKey", historyId);
}

public void JobWasExecuted(JobExecutionContext context,
                           JobExecutionException jobException)
{
    // Retrieve history id from context and update history record.
    long historyId = (long) context.Get("HistoryIdKey");
    UpdateHistoryRecord(historyId, ...);
}
4 голосов
/ 02 июня 2010

Планировщик должен поддерживать ключ, который позволяет ему сопоставлять каждую запись истории. Должен быть уникальный идентификатор задания какого-либо вида, который создается, когда задание запускается, чтобы иметь возможность выполнить это.

Вы не упоминаете такую ​​вещь, поэтому я подумал, что это стоило предложить.

ОБНОВЛЕНИЕ: я вставляю запись в базу данных при создании задания и возвращаю первичный ключ (возможно, GUID). Я бы использовал это в качестве ключа.

1 голос
/ 24 июля 2013

Если вы хотите просто обновить базу данных в конце, вы можете получить имя задания и время выполнения из IJobExecutionContext:

public void JobWasExecuted(JobExecutionContext context,
                       JobExecutionException jobException)
{
    var sql = @"INSERT INTO MyJobAuditHistory 
                (JobKey, RunTime, Status, Exception) VALUES (?, ?, ?, ?)";

    // create command etc.
    command.Parameters.Add(context.JobDetail.Key.ToString());
    command.Parameters.Add(context.JobRunTime);
    command.Parameters.Add(jobException == null ? "Success" : "Fail");
    command.Parameters.Add(jobException == null ? null : jobException.Message);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...