我在 .NET 中有一个命令可以创建一些实体并返回结果。在命令期间,它会发送一封电子邮件,其中包含有关实体的信息。它使用我通过 DI 获得的服务,并且调用是异步的。我在测试时发现发送此电子邮件会使请求花费两倍的时间。代码是这样的。
public Guid CreateInvoice(string email, string name, ...)
{
var transaction = await _context.Databse.BeginTransactionAsync();
try {
await _context.Invoice.AddAsync(new Invoice(email, name));
// Some other CRUD operations here
await _emailService.SendEmail(email, name); // This here adds the latency
// Some other CRUD
transaction.Commit();
return newInvoice.Id;
}
catch(Exception e)
{
transaction.Rollback();
}
}
我尝试从电子邮件方法的调用中删除
await
。这显然使代码更快,但随后我不知道该方法是否已发送,这意味着如果出现问题我无法回滚事务。如果方法没有发送,我想回滚所有的CRUD。
这里最好的方法是什么?我是否应该为发送添加一些重试策略,这样我就不必担心回滚。我是否应该在电子邮件服务中添加某种方法,以便在该方法失败时通知用户出现错误?我也许可以将它们分开,然后在后台调用电子邮件发送,这样它就可以独立运行。我愿意接受任何有关如何解决这个问题的想法。预先感谢。
您的业务逻辑是否要求在将对象保存到数据库之前在事务中发送电子邮件?我想不出有什么理由要求这样做。因此,只需在提交交易后发送电子邮件即可。然后,您可以确定您的事务已成功,而不必担心回滚。