我需要随后执行七个独特的流程(一个接一个)。数据存储在Mysql中。我正在考虑以下选项,如果我错了,请纠正我,或者是否有更好的解决方案。
质量要求:
从Db读取数据,最后执行七个过程(数据验证,计算1,计算2等),将处理后的数据写入数据库。
需要以块的形式处理数据。
我的解决方案和问题: 数据读取:
过程:
定义七个步骤和块,使用databean在步骤之间共享数据。但是,这不是一个好主意,因为数据进程在块中以及每个块之后,step1 writer将在databean中创建一组新数据。当这个数据库与其他步骤共享时,数据完整性将成为一个问题。
使用StepExecutionContext在步骤之间共享数据。但这可能会影响性能,因为这涉及批处理作业存储库。
只定义一个步骤,一个ItemReader和一个进程链(七个进程),并创建一个ItemWriter,将处理后的数据写入DB。但是,我将无法管理或监控每个不同的流程,所有流程都将一步到位。
答案 0 :(得分:5)
org.springframework.batch.item.support.CompositeItemProcessor
是Spring Batch Framework中的开箱即用组件,可以支持您的第二个选项。这将允许你做到以下几点;
- 在您的设计/解决方案中保持分离,以便从数据库中读取(itemreader)
- 保持每个处理器“关注点”和配置的分离
- 允许任何单个处理器通过返回null来“关闭”块,而不管先前的进程
CompositeItemProcessor
遍历一个代理循环,因此它与一个动作模式“相似”。它在您描述的场景中非常有用,并且仍然允许您利用Chunk好处(例外,重试,提交策略等)。
答案 1 :(得分:1)
建议:
1)使用JdbcCursorItemReader读取数据。
所有开箱即用的组件都是不错的选择,因为它们已经实现了使您的步骤可重新启动的ItemStream接口。但是就像你提到的那样,有时候,请求只是为了复杂,或者像我一样,你已经拥有了可以重用的服务或DAO。
我建议你使用ItemReaderAdapter。它允许您配置委托服务以调用以获取数据。
<bean id="MyReader" class="xxx.adapters.MyItemReaderAdapter">
<property name="targetObject" ref="AnExistingDao" />
<property name="targetMethod" value="next" />
</bean>
请注意,targetMethod必须遵守ItemReaders的读取合约(当没有更多数据时返回null)
如果您的工作不需要重新启动,您只需使用该类: org.springframework.batch.item.adapter.ItemReaderAdapter
但如果您需要重新启动作业,可以像这样创建自己的ItemReaderAdapter:
public class MyItemReaderAdapter<T> extends AbstractMethodInvokingDelegator<T> implements ItemReader<T>, ItemStream {
private long currentCount = 0;
private final String CONTEXT_COUNT_KEY = "count";
/**
* @return return value of the target method.
*/
public T read() throws Exception {
super.setArguments(new Long[]{currentCount++});
return invokeDelegateMethod();
}
@Override
public void open(ExecutionContext executionContext)
throws ItemStreamException {
currentCount = executionContext.getLong(CONTEXT_COUNT_KEY,0);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
executionContext.putLong(CONTEXT_COUNT_KEY, currentCount);
log.info("Update Stream current count : " + currentCount);
}
@Override
public void close() throws ItemStreamException {
// TODO Auto-generated method stub
}
}
因为开箱即用的itemReaderAdapter不可重启,所以您只需创建自己的实现ItemStream
2)关于7步与1步。
我会在这一步上使用compositeProcessor进行一步。 7步选项只会带来IMO的问题。
1)7步databean:所以你的编写器在一个数据库中提交,直到第7步...然后第7步编写器尝试提交真正的数据库和繁荣错误!全部丢失,批次必须从步骤1重新启动!!
2)带有上下文的7个步骤:可能会更好,因为您将在spring批量元数据中保存状态。但是将大数据存储在springBatch的元数据中不是一个好习惯!!
3)是去IMO的方式。 ; - )