正如我已经了解到为什么CQRS存储库发布事件而不是事件存储?这是CQRS存储库发布事件的任务.到现在为止还挺好.
当然,存储事件并发布它们应该在一个单一的事务中.从技术上讲,这意味着将一个(或多个)记录写入商店,并将一个(或多个)事件发布到消息总线.因此,简单的数据库事务是不够的,它应该是分布式的.
现在,不幸的是,许多NoSQL数据库(例如MongoDB)不支持符合ACID的事务,甚至没有谈论在分布式事务中发生的可能性.此外,还有一些消息队列也不支持分布式事务.
所以问题是:我该如何处理?
是否有推荐使用的模式?
想象一下情况:
var txn = new DatabaseTransaction();
var entry = txn.Database.Load<Entry>(id);
entry.Token = "123";
txn.Database.Update(entry);
PublishRabbitMqMessage(new EntryUpdatedMessage { ID = entry.ID });
// A bit more of processing
txn.Commit();
现在,消费者EntryUpdatedMessage可能会在提交事务之前获取此消息txn,因此无法查看更新.
现在,我知道RabbitMQ本身就支持事务,但我们不能真正使用它们,因为我们IModel为每个发布创建一个新的,并且在我们的场景(ASP.NET Web应用程序)中使用每线程模型非常麻烦.
我想到了在提交数据库事务时要发布的消息列表,但这是一个非常臭的解决方案.
处理这个问题的正确方法是什么?
根据http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young,负责使用事件发布者发布事件的组件是存储库.
我的问题很简单:为什么?
在这篇博文中,我们被告知:
域存储库负责发布事件,这通常在单个事务内部,同时将事件存储在事件存储中.
我希望这可以作为事件存储的任务:一旦存储了一个事件(或多个事件),它就会被发布.
那为什么它在存储库中呢?