【发布时间】:2020-08-07 06:00:39
【问题描述】:
我在这里扩展这个How does Spring Batch CompositeItemWriter manage transaction for delegate writers? 问题:
在我的情况下,我有一个下面的CompositeItemWriter,它将数据写入同一数据库的多个表中,在写入数据之前它通过实现各种业务规则来转换数据。在这里,一条记录可能满足不同的业务规则等。因此,一位作者可能获得比其他人更多的数据。
@Bean
public CompositeItemWriter<Employee> EmployeeCompositeWriter() throws Exception {
List<ItemWriter<? super Employee>> employee = new ArrayList<>();
employee.add(employeeWriter());
employee.add(departmentWriter());
employee.add(stockWriter());
employee.add(purchaseWriter());
CompositeItemWriter<Employee> compositeItemWriter = new CompositeItemWriter<>();
compositeItemWriter.setDelegates(employee);
compositeItemWriter.afterPropertiesSet();
return compositeItemWriter;
}
场景 - 假设第一作者工作得很好,第二作者产生异常,然后第三和第四作者没有被调用这是由于事务滚动而在 Spring Batch 中默认的Automic 性质返回。
这里即使第二个写入器出现任何异常,我想成功调用第三个和第四个写入器并保存数据,我也想成功保存第一个写入器和第二个写入器的数据..只有我想要的异常数据在SkipListener 的帮助下存储到错误表中,以识别哪些记录是垃圾或垃圾。
解决方案 - 为了实现上述场景,我们在每个写入器的写入方法上添加了@Transactional(propagation = Propagation.REQUIRES_NEW),第一个写入器现在保存数据,第二个写入器生成异常(使用namedJdbcTemplate.batchUpdate() 批量更新数据) 我们正在缓存它并重新抛出它,但我们可以看到 提交级别降低到 1(偏离路线以识别准确的垃圾记录)并且当第二个作者再次出现异常时,第一个作者正在获取调用它并保存重复的数据,并调用第 2、3 和 4 个写入器,但垃圾记录也不会流向第 3 个和第 4 个写入器。
在这里,如果单个或多个记录是垃圾,我不希望整个批处理作业停止,因为此作业对于我们每次运行都至关重要。如果我们可以保存所有没有出现异常的数据并且仅在SkipListener的帮助下将异常数据保存到错误表中,有什么办法吗?
如果我们可以将批处理组件(例如(READER 或 PROCESSOR)部分)重用到另一个步骤中,有什么办法吗?
【问题讨论】:
-
什么都没有被跳过,那么为什么skiplistener会在这种情况下提供帮助?似乎您最好编写自己的单一作家,一次完成您想要的事情。从批处理的角度来看,只有一个写入器(不是多个),并且一切都应该(通常)成功与否(这就是写入批处理记录的本质)。
-
从批次的角度来看,没有任何内容被跳过。跳过是完全跳过的写入,而不是您想要的部分写入。这不是skiplistener的工作方式。
标签: spring spring-batch