如何使用Quartz调度程序维护作业历史记录

时间:2010-06-02 07:43:53

标签: c# java task quartz-scheduler

我想保留由Quartz调度程序安排的作业历史,其中包含以下属性:“开始时间”,“结束时间”,“成功”,“错误”。

有两个可用的接口:ITriggerListenerIJobListener(我正在使用接口的C#命名约定,因为我使用的是Quartz.NET,但可能会询问相同的问题Java版)。

IJobListenerJobToBeExecutedJobWasExecuted方法。后者提供JobExecutionException,以便您知道什么时候出错了。但是,无法关联JobToBeExecutedJobWasExecuted。假设我的工作运行了十分钟。我从t0t0+2开始(因此它们重叠)。我接到JobToBeExecuted两次调用,并在历史表中插入两个开始时间。当这两项工作都在t1t1+2完成时,我会拨打JobWasExecuted两次电话。我如何知道每次调用中要更新的数据库记录(以结束相应的开始时间来存储结束时间)?

ITriggerListener还有另一个问题。当作业失败时,无法在TriggerComplete方法中获得任何错误。

我如何获得所需的行为?

3 个答案:

答案 0 :(得分:12)

执行此操作的方法是在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, ...);
}

答案 1 :(得分:4)

调度程序必须维护一个密钥,使其关联每个历史记录条目。必须有一个独特的工作ID,当工作开始时能够实现这一点。

你没有提到这样的事情,所以我认为值得一个建议。

更新:我在创建作业时将记录插入数据库并返回主键(可能是GUID)。我会用它作为关键。

答案 2 :(得分:1)

如果您愿意最后更新数据库,可以从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);
}