请假设您有如下方法:
public void PlaceOrder(Order order)
{
this.SaveOrderToDataBase(order);
this.bus.Publish(new OrderPlaced(Order));
}
订单保存到数据库后,将一个事件发布到消息队列系统,以便同一台或另一台机器上的其他子系统处理它。
但是,如果this.bus.Publish(new OrderPlaced(Order))
调用失败怎么办?或者机器在将订单保存到数据库后就崩溃了?该事件未发布,其他子系统无法处理它。这是无法接受的。如果发生这种情况,我需要确保最终发布该事件。
我可以使用哪些可接受的策略?哪个是最好的?
注意:我不想使用分布式事务。
编辑:
Paul Sasik 非常接近,我认为我可以达到 100%。这就是我的想法:
首先在数据库中创建一个表事件,如下所示:
CREATE TABLE Events (EventId int PRIMARY KEY)
您可能想要使用 guid 而不是 int,或者您可以使用序列或标识。
然后执行以下伪代码:
open transaction
save order and event via A SINGLE transaction
in case of failure, report error and return
place order in message queue
in case of failure, report error, roll back transaction and return
commit transaction
所有事件都必须包含 EventId。当事件订阅者收到事件时,他们首先检查数据库中是否存在 EventId。
这样您就可以获得 100% 的可靠性,而不仅仅是 99.999%