3

我有一个JavaMailSender发送双重或三重消息的问题。

在控制器中:

while(size > 0) //# of emails I want to send, for example 5
{
    Item item= itemRepository.findFirstBySentFalseAndValidTrue(); //getting only emails that are not sent!
    item.getData(); // API call that adds some info to the item, takes between 5-15 seconds per item    
    if(item.isValid())
    {

            item.setHeaderName(dataService.setHeader(item.getStore(), LocaleContextHolder.getLocale()));
            item.setAddress(dataService.getAddress(item.getStore(), LocaleContextHolder.getLocale()) + item.getId());

            String email = dataService.getEmail(item.getStore());
            String footer = dataService.getFooter(item.getStore(), LocaleContextHolder.getLocale());

            if(!item.isSent()) //I check if sent here but still get double messages!
            {
                if(mailSenderService.sendEmail(item, "emails/templates/item", email, footer))
                {
                    item.setSent(true);
                }
            }

    itemRepository.save(item);
    size--;
    }
}

在我的电子邮件发送服务类中:

    final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
    final MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true, "UTF-8");

    Context ctx =  new Context(LocaleContextHolder.getLocale());
    message.setFrom(email);
    message.setTo("test@gmail.com");

    ResourceBundle labels = ResourceBundle.getBundle("messages", LocaleContextHolder.getLocale());
    mimeMessage.setHeader("Content-Type", encodingOptions);
    mimeMessage.setSubject(labels.getString("email.itme.title"), "UTF-8");


    ctx.setVariable("data", item);
    ctx.setVariable("footer", footer);

    try{        
        String processedTemplate =  templateEngine.process(template, ctx);
        mimeMessage.setContent(processedTemplate, encodingOptions);
        this.mailSender.send(mimeMessage);

    } catch(Exception e){
      e.printStackTrace();
    }

    return true;
}

我只是假设这是我的电子邮件发送类中的一个问题,但也许 api 调用太慢以至于方法执行时间过长并发送重复消息?有时,当我只发送几封电子邮件(例如 3 封)时,这没问题,而且不会发送重复邮件。当我想发送 20 或 30 时,一切都需要大约 15 分钟,而且我得到了重复(我无法控制 API 的响应时间,有时它更快有时它超级慢)。有什么方法可以调试它并查看何时调用哪个方法以及为什么会得到这些重复项?

编辑:那是我的 itemRepository 实现:

 @Repository
 @Qualifier(value = "itemRepository")
 @Transactional
 public interface itemRepository extends CrudRepository<Item, Long> {

 public Item save(Item item);
 public Item findFirstBySentFalseAndValidTrue();
 }
4

1 回答 1

0

这部分:

while(size > 0) //# of emails I want to send, for example 5
{
    Item item= itemRepository.findFirstBySentFalseAndValidTrue(); //getting only emails that are not sent!

没有任何意义。您正在指定要发送的电子邮件的静态数量,然后永远不要减少此值,然后从存储库中调用一封尚未发送的电子邮件,并对其进行处理。这是一个糟糕的设计。您可能会得到重复,因为没有什么可以阻止您的程序使用这行代码重复检索相同的记录:Item item= itemRepository.findFirstBySentFalseAndValidTrue();在它有机会更新记录之前。

相反,您应该做的是查询您的存储库以获取符合某些条件的未发送电子邮件列表,然后在此返回的列表上执行循环以发送电子邮件,然后更新存储库中的记录。

于 2015-07-20T13:22:02.333 回答