当前位置: 首页 > 知识库问答 >
问题:

在ItemProcessor中跳过异常导致二次行为

田佐
2023-03-14
@Bean
public Job job() {
    return jobBuilderFactory.get("job").start(step(null)).build();
}

@Bean
public Step step(ReaderProcessorWriter readerProcessorWriter) {
    return stepBuilderFactory.get("step")
            .<Integer, Integer>chunk(20).faultTolerant()
            .skip(RuntimeException.class).skipLimit(10)
            .reader(readerProcessorWriter)
            .processor(readerProcessorWriter)
            .writer(readerProcessorWriter)
            .build();
}
@Component
public static class ReaderProcessorWriter extends ListItemReader<Integer> implements ItemProcessor<Integer, Integer>, ItemWriter<Integer> {
    private int run;

    public ReaderProcessorWriter() {
        super(List.of(0, 1, 2, 3, 4, 5, 6, 7,8 ,9));
    }

    @Override
    public Integer process(Integer integer) {
        // Probably some long computation involving lots of DB Reading, lasting minutes at worst
        if (integer >= 5) {
            System.out.println("FAIL: " + integer);
            throw new RuntimeException("Hue hue");
        }
        System.out.println("OK: " + integer);
        return integer;
    }

    @Override
    public void write(List<? extends Integer> list) {
        if (run++ == 0) {
            throw new RuntimeException("Writer");
        }
        System.out.println(list);
    }
}
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
FAIL: 5
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
FAIL: 6
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
FAIL: 7
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
FAIL: 8
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
FAIL: 9
OK: 0
OK: 1
OK: 2
OK: 3
OK: 4
OK: 0
[0]
OK: 1
[1]
OK: 2
[2]
OK: 3
[3]
OK: 4
[4]
    null
    null

共有1个答案

屈浩波
2023-03-14

您可以尝试将容错处理器配置为非事务性的。然后,它将缓存成功处理的项的处理结果,以便在回滚的情况下和在再次处理块的重试期间,它只从缓存中获得处理结果,而不是再次处理成功的项。

@Bean
public Step step(ReaderProcessorWriter readerProcessorWriter) {
    return stepBuilderFactory.get("step")
            .<Integer, Integer>chunk(20).faultTolerant()
            .skip(RuntimeException.class).skipLimit(10)
            .reader(readerProcessorWriter)
            .processor(readerProcessorWriter)
            .processorNonTransactional()
            .writer(readerProcessorWriter)
            .build();
}

您必须看看它是否适合您的用例。当使用JPA处理这些项时,我觉得更安全的是,在回滚的情况下,应该丢弃在回滚事务中加载和处理的所有实体,最好不要在另一个新事务中重用它们,因为实体将在新事务中分离,这对我来说似乎使事情变得更加复杂。

如果重新处理一个项目需要相当长的时间,我将尝试看看处理一个项目中的瓶颈操作是否可以微调,比如使用缓存来缓存那些扩展操作的结果。

 类似资料:
  • 问题内容: 我对Java线程技术比较陌生,并且我注意到,每次使用Thread.sleep()时,我都必须捕获InterrupetdException。 哪种行为会导致这种情况,并且在具有监视器线程的简单应用程序中,我可以忽略该异常吗? 问题答案: 好吧,如果其他一些线程调用thread.interupt(),则在该线程处于休眠状态时,您将获得Exception。是的,您可能只需将try..catc

  • (2016.3.15更新) 上周我遇到了一个奇怪的问题,我想和你讨论一下这个问题。 但是,如果我使用sendMessage(SearchHandler.Object...)而不是runOnUiThread,一切都会很顺利!! java: SearchActivity.java: 2)在运行getActivity().runonuithread()之前,首先判断getActivity()==null

  • 11.2. 一致的异常层次 Spring提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以DataAccessException 为根的异常层次。这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的风险。 除了对JDBC异常的封装,Spring也对Hibernate异常进行了封装,把它们从一种专有的checked异常 (Hiberna

  • 问题内容: 如果发生某些异常,我试图使工作没有。 这些文档讨论的是在内部使用,但是如何在内部使用呢?以下代码不起作用: 问题答案: 正如Michael Minella建议的那样,我在Tasklet中实现了此功能: 以Spring XML配置为例:

  • 问题内容: 我该如何跳过第一次遇到问题。 问题答案: 该挂钩可用于存储任何可变值,因此您可以存储一个布尔值,指示是否是第一次运行效果。 例

  • 问题内容: 根据python文档,自python 2.5开始支持相对导入和内部包引用。我当前正在运行Python 2.7.3。因此,我尝试在自己的程序包中实现此功能,以便将其用于更简单的导入。我很惊讶地发现它引发了SyntaxError异常,我希望有人可以帮助您找到原因。 我设置了一个测试目录进行测试: 两个__init__.py模块都为空。其他模块是: 当我尝试导入second_level模块时