我理解如何使用实体框架来实现一个工作单元,并且只在执行完整单元后提交更改,但是我该如何更进一步呢?例如,以下需要在一个事务下发生
CreateUser(...)
{
//1.) New up user object
//2.) Add newly created object to database
//3.) Send Email
//4.) Commit transaction ( ensures email is successfully sent AND object is created in database, else transaction fails
}
我不太确定如何确保在一次交易中发送电子邮件和在数据库中保存用户都发生。非常感谢任何建议
答案 0 :(得分:2)
并非所有资源都是交易性的。电子邮件就是其中之一。因此,当其他资源在事务中失败时,不能指望发送电子邮件会被回滚。
有一些替代解决方案:
1)在最后一步调用非事务性资源。
就像你在创建用户示例中所做的那样。在这种情况下,所有业务约束都经过检查和通过,失败的唯一原因是基础设施问题,这在现实世界中并不经常发生(需谨慎维护)。在基础设施故障发生时做出一些补偿。这可以自动或手动完成,取决于它发生的频率。例如,如果发送了电子邮件,但回滚了用户设置,您可能会告诉他/她您很抱歉(这非常重要:P)但是设置有问题,请再试一次。
2)最终应用一致性
使用事务资源来触发进程。例如,您可以使用消息传递(如果使用2阶段提交,则使用全局事务)来通知发送电子邮件。
CreateUser(...)
{
//1.) New up user object
//2.) Add newly created object to database
//3.) Publish user setup event by messaging
//4.) Commit transaction ( ensures message is successfully sent AND object is created in database, else transaction fails
}
在任何情况下,失败和不一致都或多或少地发生。你需要评估它是否可以接受。