我在使用 JavaMailSender
时遇到问题,该问题发送两条或三条消息。
在 Controller 中:
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 的响应时间,有时会更快,有时会 super 慢)。有什么方法可以调试它并查看何时调用哪个方法以及为什么我会得到这些重复项?
编辑: 这就是我的 itemRepository 实现:
@Repository
@Qualifier(value = "itemRepository")
@Transactional
public interface itemRepository extends CrudRepository<Item, Long> {
public Item save(Item item);
public Item findFirstBySentFalseAndValidTrue();
}
最佳答案
这部分:
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();
.
您应该做的是查询存储库以获取符合某些条件的未发送电子邮件列表,然后对此返回的列表执行循环以发送电子邮件,然后更新存储库中的记录。
关于Java邮件发送器发送重复的电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31517033/