Spring Batch JMSItemReader在会话事务处理模式中提供重复数据

时间:2017-01-15 11:06:01

标签: activemq spring-batch spring-transactions spring-jms

我有一个单步的弹簧批处理作业。我正在使用JMSItemReader,其中jmstemplate是会话事务处理,我的编写器只是执行一些业务逻辑。每当默认情况下发生任何异常并且重试耗尽时,自动批量大小变为1并逐个重试所有项目。

我正在定义这样的步骤。

stepBuilderFactory.get("step")
                .<String, String> chunk(10)
                .reader(reader())
                .processor(processor)
                .writer(writer)
                .faultTolerant()
                .processorNonTransactional()
                .retry(SomeException.class)
                .retryLimit(2)
                .backOffPolicy(backOffPolicy)
                .skip(SomeException.class)
                .skipLimit(Integer.MAX_VALUE)
                .build();

我面临的问题是这样的 输入为:1,2,3,4,5,6,7,8,9,10

  1. 批次1,2,3,4,5中的项目
  2. 作家
  3. 发生例外
  4. 重复2次并重新耗尽
  5. 现在它会像这样逐一尝试

    项目 - 1 - 错误

    项目 - 2 - 成功

    项目 - 3 - 错误

    item - 4 - 错误

    项目 - 5 - 成功

  6. 发生错误,因此跳过第1,3,4项并成功处理2,5,

    1. 这是问题 - 接下来我应该将6,7,8,9,10作为批处理进行处理,但是我再次获得1,2,3,4,5批次并且无限期执行。
    2. 注意:当sessionTransacted为false时,它可以正常工作,但在这种情况下,如果ActiveMQ队列出现异常,则不会回滚消息。

      感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我认为这是有效的行为,因为有事务回滚并且没有从队列中删除消息,所以消息可供下一个侦听器线程读取。并且你已经跳过了Integer.MAX_VALUE的限制,因此它会重试无限时间(几乎就像你有大的skiplimit一样)。我相信您需要为正在读取的队列配置死信队列,以便在某些重试后,如果消息损坏/无效,则应移至DLQ,以便手动干预以处理消息。因此,相同的消息不再被重新传递给听众。

相关问题