Spring Batch 2.1.8 当石英 cron 触发器触发时运行作业的单个实例

发布于 2024-12-21 14:37:19 字数 582 浏览 1 评论 0原文

我设置了一个弹簧批石英。我有两个作业配置并并行运行。这些作业正在读取文件,然后将一些数据写入数据库。这是棘手的部分,文件名是在我的执行侦听器的 beforeJob() 方法中计算的。每个作业完成后,afterJob() 将计算下一个文件名。文件名具有以下模式 xxxxxx.nnnn ,其中 nn.. 是数字,有时序列可能会缺少数字,因此我尝试“跳过”那些缺少的段落,当我找到现有数字时启动作业。
我想知道是否可以限制每次 cron 触发器触发时启动的作业数量?我想在 chron 触发器触发后启动一项作业。

例如:

  1. 中午 12.30 作业启动。
  2. 该作业尝试找到正确的文件
  3. 作业因 FileNotFound 而失败(配置为不可跳过的异常)
  4. 作业完成后,文件名计数器递增

现在,当触发器触发时,我会得到 4 个或更多作业异步执行相同类型。在我的批量设置中,我有两个 配置为每小时启动一个,间隔 5 分钟。这些工作都遵循示例中提供的流程。结论:是否可以在 cron 触发器触发后启动单个作业并使两种作业类型并行运行。

彼得

I have a spring batch quartz set up. I have two jobs configured and running in parallel. The jobs are reading a file and then writing some data to the db. Here is the tricky part, the file names are calculated within the beforeJob() method of my execution listener. After each job finishes, the afterJob() would then calculate the next fileName. File names have the following pattern xxxxxx.nnnn where nn.. are numbers and sometimes the sequence can have numbers missing, therefore I am attempting "jump" over those missing passages and when I find an existing number to launch the job.
I want to know if it's possible to restrict the number of jobs launched each time the cron trigger fires? I want to have a single job launched after a chron trigger fires.

For example:

  1. At 12.30 PM the job is launched.
  2. The job tries to find the correct file
  3. The job fails with FileNotFound ( which is configured as a non -skippable exception)
  4. After the job, the fileName counter is incremented

Right now, when the trigger fires, I get like 4 or more jobs of the same type being executed asynchronously. In my batch set-up I have two <jobs> configured to launch one after the other each hour within a 5 minutes interval of one another. The jobs both fallow the flow provided in the example. In conclusion : Is it possible to launch a single job after a cron trigger fires and have both job types run in parallel.

Peter

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

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

发布评论

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

评论(1

软的没边 2024-12-28 14:37:19

您的作业在执行之前应该知道要处理什么文件。例如,文件名应作为作业参数传递。删除 JobExecutionListener 并添加 StepExecutionListener 以通过 StepExecution#getJobParameters() 访问作业参数。一份工作=一份文件。

现在,您希望通过调度程序确保在某个时间点仅运行一项作业。您可以通过两种方式实现此目的:

• 使用异步任务执行器。在这种情况下,每次启动作业时,它都不会在后台执行(除非您的调度程序不会每次在新线程中触发计时器事件)。

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
    <property name="taskExecutor" ref="taskExecutor" />
</bean>

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

• 如果您对其他需要在后台执行的作业使用相同的作业启动器,则需要使用 ThreadPoolTask​​Executor,但您可以手动检查作业是否正在运行:

for (final JobInstance jobInstance : jobExplorer.getJobInstances(jobName(), 0, LOOK_BEHIND_INSTANCES)) {
    for (final JobExecution jobExecution : jobExplorer.getJobExecutions(jobInstance)) {
        final BatchStatus status = jobExecution.getStatus();

        if (status.isRunning()) {
            // Ops:
            break;
        }
    }
}

Your job should know what file to process before it is executed. E.g. the file name should be passed as job parameter. Remove JobExecutionListener and add StepExecutionListener to access job parameters via StepExecution#getJobParameters(). One job = one file.

Now from your scheduler you want to make sure that only one job is run at one point of time. You can achieve this in two ways:

• Using the async task executor. In this case each time you launch the job, it will not be executed in a background (unless your scheduler does not fire timer events each time in new thread).

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
    <property name="taskExecutor" ref="taskExecutor" />
</bean>

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

• If you use the same job launcher for other jobs, which need to be executed in background, you need to use ThreadPoolTaskExecutor but you can manually check if the job is running:

for (final JobInstance jobInstance : jobExplorer.getJobInstances(jobName(), 0, LOOK_BEHIND_INSTANCES)) {
    for (final JobExecution jobExecution : jobExplorer.getJobExecutions(jobInstance)) {
        final BatchStatus status = jobExecution.getStatus();

        if (status.isRunning()) {
            // Ops:
            break;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文