1

我们正在开发一个基于 Spring 批处理和 Hibernate 的应用程序,它将负责发送 1000 封电子邮件。

简而言之,目前只有一个步骤定义了一个作业。

<job id="emailJob" xmlns="http://www.springframework.org/schema/batch" restartable="true"
     job-repository="jobRepository">
    <step id="emailJobFetchUsers">
        <tasklet>
            <chunk reader="emailItemReader" processor="emailItemProcessor" writer="emailItemWriter" commit-interval="1"/>
        </tasklet>
        <end on="COMPLETED"/>
        <fail on="FAILED"/>
    </step>
    <listeners>
        <listener ref="loggingListener"/>
    </listeners>
</job>
  • emailItemReader 扩展了 HibernateCursorItemReader 并将返回行的实体(在这种情况下,代表客户选择的电子邮件的记录)
  • emailItemProcessor 生成并发送客户特定的电子邮件
  • emailItemWriter 只是更新实体,其中包含一些信息,例如上次发送日期

虽然这可行,但我不确定它是否应该都是一个步骤,或者是否应该有一个步骤负责每个动作。我主要关心的是可重启性和恢复。也就是说,一个用户会发生这种异常(可能是由于电子邮件地址无效或生成电子邮件的问题),或者如果应用程序服务器出现故障并重新启动,我希望它能够从它离开的地方接收发送电子邮件离开。

任何人都可以就上述问题提出建议吗?

谢谢,

4

1 回答 1

0

是的,它应该可以重新启动。检查读者超类的 javadoc。但是,您需要注意以下事项:

  • 您需要在查询中保持顺序 - 阅读器将从失败的项目开始,因此每个查询执行必须以相同的顺序返回项目
  • 如果 itemWriter 中的实体修改影响查询结果可能会很棘手 - 如果您按上次发送日期过滤,那么它将无法按预期工作

更重要的是,我相信如果发生以下情况:

  1. 作业执行失败
  2. 将新客户插入数据库\
  3. 工作重新开始

那么查询结果也可能与第一次(失败)执行期间不同。如果您的应用程序中可能出现这种情况,那么我建议添加一些条件来防止它 - 例如在查询中添加检查以跳过在第一次作业执行时间后注册的客户。

于 2013-03-02T00:38:25.747 回答