Transactions CQRS:存储事件并发布它们-如何以安全的方式执行此操作?

Transactions CQRS:存储事件并发布它们-如何以安全的方式执行此操作?,transactions,cqrs,event-sourcing,neventstore,Transactions,Cqrs,Event Sourcing,Neventstore,正如我在中了解到的,发布事件是CQRS存储库的任务。到目前为止,一切顺利 当然,存储和发布事件应该在一个事务中完成。从技术上讲,这意味着将一个(或多个)记录写入存储,并将一个(或多个)事件发布到消息总线。因此,一个简单的数据库事务是不够的,它应该是一个分布式事务 现在,不幸的是,许多NoSQL数据库(如MongoDB)不支持符合ACID的事务,甚至不讨论在分布式事务中发生的可能性。此外,还有一些消息队列也不支持分布式事务 所以问题是:我该如何处理 是否有推荐的模式可供使用?您的存储库可以发布事件

正如我在中了解到的,发布事件是CQRS存储库的任务。到目前为止,一切顺利

当然,存储和发布事件应该在一个事务中完成。从技术上讲,这意味着将一个(或多个)记录写入存储,并将一个(或多个)事件发布到消息总线。因此,一个简单的数据库事务是不够的,它应该是一个分布式事务

现在,不幸的是,许多NoSQL数据库(如MongoDB)不支持符合ACID的事务,甚至不讨论在分布式事务中发生的可能性。此外,还有一些消息队列也不支持分布式事务

所以问题是:我该如何处理

是否有推荐的模式可供使用?

您的存储库可以发布事件,而不必发布。本例中的解决方案是将事件存储用作队列。您将拥有一个后台进程,该进程监视事件存储区中的新事件,将它们发布到(例如)总线,然后将它们标记为已调度

和往常一样,这是一种权衡。您可能需要至少处理一次消息传递和幂等处理。它比使用简单的分布式事务更复杂


乔纳森·奥利弗(Jonathan Oliver)写了几篇关于这个话题的文章,可能会对你有所帮助:,

谢谢你,非常有用。关于事件存储的监控-如果没有轮询,如何实现这一点?在不引入2PC的情况下,是否有更灵敏的机制来实现这一点?