Spring重试for循环

问题描述

我的RetryTemplate配置:

@Configuration
@EnableRetry
public class RetryTemplateConfig {

    @Value("${spring.retry.attempts}")
    private int maxAttempts;

    @Value("${spring.retry.period}")
    private long backOffPeriod;

    @Bean
    public RetryTemplate retryTemplate() {
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(maxAttempts);
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(backOffPeriod);
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        return retryTemplate;
    }
}

计划的方法,该方法调用使用Retry的方法:

@Scheduled(cron = "${schedule.cron.update.users}")
    public void sendToUsers() throws Exception {
        log.info("Scheduled sending for users started");
        try {
            mailSender.sendToUsers();
        } catch (MessagingException | IOException | TemplateException e) {
            log.error("Error occurred while sending email message to users: {}",e.toString());
        }
        log.info("Scheduled sending for users finished");
    }

我要使用RetryTemplate的方法:

public void sendToUsers() throws Exception {
        String subject = reportGenerationService.getEmailSubjectForUser();
        Map<String,List<BadUtmMark>> utmMarksGroupedByEmail = userService.getUtmMarksGroupedByEmail(LocalDate.now());
        if (utmMarksGroupedByEmail.isEmpty()) {
            log.info("All's fine - no broken utm marks in database. Emails to users will not be send.");
        }
        for (Map.Entry<String,List<BadUtmMark>> pair : utmMarksGroupedByEmail.entrySet()) {
            retryTemplate.execute(retryContext -> {
                String emailTo = pair.getKey();
                List<BadUtmMark> badUtmMarks = pair.getValue();
                String report = reportGenerationService.getReportForUser(emailTo,badUtmMarks,template);
                MimeMessage mimeMessage = getMimeMessage(subject,report,Collections.singletonList(emailTo));
                log.info("Message will be sent to: {}; from: {}; with subject: {}",pair.getKey(),from,subject);
                mailSender.send(mimeMessage);
                return true;
            });
        }
    }

预期的行为:我想发送5个人的电子邮件。如果发生错误,请尝试再次向该用户发送电子邮件5次,然后如果重试已用尽,请继续操作,并在for循环中为下一个用户发送电子邮件。

真正的行为:如果发生错误,服务将捕获异常并停止循环。

如果我将重试逻辑移至此方法:

@Scheduled(cron = "${schedule.cron.update.users}")
public void sendToUsers() throws Exception {
    log.info("Scheduled sending for users started");
    try {
        retryTemplate.execute(retryContext - > {
            log.warn("Sending email to users. Attempt: {}",retryContext.getRetryCount());
            mailSender.sendToUsers();
            return true;
        });
    } catch (MessagingException | IOException | TemplateException e) {
        log.error("Error occurred while sending email message to users: {}",e.toString());
    }
    log.info("Scheduled sending for users finished");
}

它的效果更好,但仍达不到我的期望。在这种情况下,如果发生错误,服务将尝试再次发送电子邮件5次,但是如果重试已用尽,服务将停止循环。因此,如果其中一个用户发生错误,该服务将尝试为此用户再发送5次,然后停止运行,并忽略地图中的其他用户。

但是我想对地图中的每封电子邮件进行5次重试。我该怎么做?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)