Questions tagged «event-sourcing»


2
如何在CQRS中创建新的聚合根?
我们应该如何在cqrs体系结构中创建新的聚合根?在此示例中,我想创建新的聚合根AR2,其中包含对第一个AR1的引用。 我正在使用AR1方法作为起点来创建AR2。到目前为止,我看到的选择很少: 在AR1的内部方法中,createAr2RootOpt1我可以new AR2()使用具有访问存储库权限的域服务立即将该对象调用并将其保存到db。 我可以在第一个聚合根发出事件,例如。SholdCreateAR2Event然后有无状态的传奇对此做出反应并发出命令CreateAR2Command,该命令随后被处理并实际创建AR2并发出AR2CreatedEvent。如果使用事件源SholdCreateAR2Event,则不会将其保留在事件存储中,因为它不会影响第一个聚合根的状态。(或者我们还是应该将其保存在事件存储中?) class AR1{ Integer id; DomainService ds; //OPTION 1 void createAr2RootOpt1(){ AR2 ar2 = new AR2(); ds.saveToRepo(ar2); } //OPTION 2 void createAr2RootOpt2(){ publishEvent(new SholdCreateAR2Event()); //we don't need this event. Shoud it still be preserved in event store? } } class AR2{ Integer id; Integer ar1Id; void …

3
事件源,一个事件,两个聚合的状态已更改
我正在尝试学习DDD和相关主题的方法。我想到了一个简单的有界上下文来实现“银行”的想法:有帐户,可以在它们之间存入,提取和转移资金。保留更改历史也很重要。 我确定了Account实体,并且事件来源可以很好地跟踪其中的更改。其他实体或值对象与该问题无关,因此我不会提及它们。 考虑存款和取款时-这相对简单,因为只修改了一个汇总。 转移时有所不同-必须通过一个MoneyTransferred事件来修改两个聚合。DDD不赞成在一个事务中修改多个聚合。另一方面,事件源的规则是将事件应用于实体并基于它们修改状态。如果事件可以简单地存储在数据库中,那就没有问题。但是,为了防止同时修改事件源实体,我们必须对每个聚合的事件流实施某种版本控制(以保持其事务界限)。版本控制带来了另一个问题-我无法使用简单的结构来存储事件并读回它们以将其应用于聚合。 我的问题是-如何将这三个原则结合在一起:“一个交易合计一笔交易”,“事件->总交易变更”和“防止并发修改”?

1
仅在很少有写入的情况下才使用事件源吗?
我正在阅读事件源,不能停止问自己,这是否仅在非常罕见的情况下才有意义,在这种情况下,写操作很少或需要进行军事级审核。 具有非凡用途的非例外系统每天可能会产生成百上千的写入,相当于每年运行一百万或2次写入(因此发生事件)。与从传统存储中直接读取的内容相比,合并数百万个对象(事件)只是为了获得当前状态,这听起来很荒谬。但是,事件源位于某些性能最高的系统(例如LMAX)的背后。 那么,我想念什么?从事件流恢复状态是否通常已经完成?还是这种想法很少需要这样做,而是完全使用其他存储来进行常规操作(即使用CQRS的查询存储),并且仅在特殊情况下(例如复制,审核等)从事件中恢复?

4
CQRS + ES中的对象应该在哪里进行完全初始化:在构造函数中,还是在应用第一个事件时?
在OOP社区中似乎已经达成广泛的共识,即类构造函数不应将对象部分或什至完全未初始化。 我所说的“初始化”是什么意思?粗略地讲,原子过程将新创建的对象带入其所有类不变式都成立的状态。它应该是发生在对象上的第一件事(每个对象只能运行一次),并且任何内容都不应该拥有未初始化的对象。(因此,经常建议在类构造函数中执行对象初始化。出于同样的原因,Initialize方法常常被皱眉,因为这些方法打破了原子性并使得可以持有和使用尚未使用的对象成为可能。处于定义良好的状态。) 问题:当CQRS与事件源(CQRS + ES)结合使用时,对象的所有状态变化都被捕获在一系列有序的事件(事件流)中,我想知道对象何时真正达到完全初始化的状态:在类构造函数的末尾,还是在将第一个事件应用于对象之后? 注意:我避免使用“聚合根”一词。如果愿意,在阅读“对象”时将其替换。 讨论示例:假定每个对象由某个不透明Id值唯一标识(请考虑GUID)。可以使用相同的Id值在事件存储中标识表示该对象状态变化的事件流:(不用担心正确的事件顺序。) interface IEventStore { IEnumerable<IEvent> GetEventsOfObject(Id objectId); } 进一步假设有两种对象类型Customer和ShoppingCart。让我们关注ShoppingCart:创建时,购物车为空,必须与一个客户完全关联。最后一点是类不变式:ShoppingCart与a无关的对象Customer处于无效状态。 在传统的OOP中,可以在构造函数中对此建模: partial class ShoppingCart { public Id Id { get; private set; } public Customer Customer { get; private set; } public ShoppingCart(Id id, Customer customer) { this.Id = id; this.Customer = customer; } } …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.