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

发布于 2024-09-03 15:56:04 字数 766 浏览 4 评论 0原文

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

有两个接口可用于此:ITriggerListenerIJobListener (我使用接口的 C# 命名约定,因为我使用的是 Quartz.NET,但同样的问题可能是要求 Java 版本)。

IJobListener 有一个 JobToBeExecuted 和一个 JobWasExecuted 方法。后者提供了一个JobExecutionException,以便您知道何时出现问题。但是,无法关联 JobToBeExecutedJobWasExecuted。假设我的工作运行十分钟。我从 t0t0+2 开始(因此它们重叠)。我收到两次对 JobToBeExecuted 的调用,并将两个开始时间插入到我的历史记录表中。当两个作业在 t1t1+2 完成时,我收到两次对 JobWasExecuted 的调用。我如何知道在每次调用中要更新哪些数据库记录(以存储结束时间及其相应的开始时间)?

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

我如何获得所需的行为?

I'd like to maintain a history of jobs that were scheduled by a Quartz scheduler containing the following properties: 'start time', 'end time', 'success', 'error'.

There are two interfaces available for this: ITriggerListener and IJobListener (I'm using the C# naming convention for interfaces because I'm using Quartz.NET but the same question could be asked for the Java version).

IJobListener has a JobToBeExecuted and a JobWasExecuted method. The latter provides a JobExecutionException so that you know when something went wrong. However, there is no way to correlate JobToBeExecuted and JobWasExecuted. Suppose my job runs for ten minutes. I start it at t0 and t0+2 (so they overlap). I get two calls to JobToBeExecuted and insert two start times into my history table. When both jobs finish at t1 and t1+2 I get two calls to JobWasExecuted. How do I know what database record to update in each call (to store an end time with its corresponding start time)?

ITriggerListener has another problem. There is no way to get any errors inside the TriggerComplete method when a job failed.

How do I get the desired behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

各空 2024-09-10 15:56:04

实现此目的的方法是在 JobToBeExecuted 中生成一个标识符,将其存储在 JobExecutionContext 中,并从 中的 JobExecutionContext 中再次检索它作业已执行

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, ...);
}

The way to do this is to generate an identifier in JobToBeExecuted, store it in the JobExecutionContext and retrieve it again from the JobExecutionContext in 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, ...);
}
红颜悴 2024-09-10 15:56:04

调度程序必须维护一个密钥,使其能够关联每个历史记录条目。必须在作业启动时创建某种唯一的作业 ID 才能完成此任务。

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

更新:当创建作业时,我会在数据库中插入一条记录并取回主键(可能是 GUID)。我会用它作为钥匙。

The scheduler has to maintain a key that lets it correlate each history entry. There must be a unique job ID of some kind that's created when a job kicks off to be able to accomplish this.

You don't mention such a thing, so I thought it was worth a suggestion.

UPDATE: I'd INSERT a record into the database when a job is created and get back the primary key (maybe a GUID). I'd use that as the key.

当爱已成负担 2024-09-10 15:56:04

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

If you're happy to just update the database at the end, you can get the job name and run time from the 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文