小编Mar*_*edy的帖子

聚合应该是事件处理程序

在研究了大量材料和示例之后,我目前正在开始第一次尝试DDD/CQRS/ES系统.

1)我已经看到了事件源代码示例,其中Aggregates是事件处理程序,并且每个事件的Handle方法是改变对象实例上的状态(它们为将改变状态的事件实现IHandleEvent <EventType>接口)

2)我还看到了一些例子,其中Aggregates看起来就像是对域建模的普通经典实体类.另一个事件处理程序类涉及改变状态.

当然,当从存储库调用重建聚合时,状态由事件处理程序在聚合上进行突变,该存储库调用获取该聚合的所有先前事件,并且当命令处理程序调用聚合上的方法时.虽然在后者中我看过事件在命令处理程序而不是聚合中发布的例子,但我确信这是错误的.

我的问题是方法(1)和(2)之间的利弊是什么

cqrs event-sourcing

10
推荐指数
1
解决办法
4857
查看次数

使用对多个客户端的乐观并发检查实现事件存储

我正在尝试使用符合我所看到的各种 Greg Young 启发示例的实践和原则来实现一个事件溯源系统。

我了解版本检查逻辑是如何工作的,并且在保存聚合时,如果当前版本与预期版本不匹配,则意味着另一个会话/客户端应用程序在您之前更新了聚合。

我也知道您可以制定一种在保存并发事件时追溯解决冲突的方法,这个问题与这样做无关。

我想了解的是,在使用 nosql 数据库(例如 ravendb)作为事件存储的特定实现中,我将如何确保写入的事件不会因竞争条件而与版本号重叠。

以下代码来自一个示例项目来说明:

Repository<TAggregate>存储库类中有一个保存方法

    public void Save(AggregateRoot aggregate, int expectedVersion)
    {
        if (aggregate.GetUncommittedChanges().Any())
        {
            lock (_lockStorage)
            {
                var item = new T();

                if (expectedVersion != -1)
                {
//issue if two processes get to this line of code below together 
//and both have the same 'version to be expected' then start writing together
                    item = GetById(aggregate.Id); 
                    if (item.Version != expectedVersion)
                    {
                        throw new ConcurrencyException(string.Format("Aggregate {0} has been previously modified",
                                                                     item.Id));
                    } …
Run Code Online (Sandbox Code Playgroud)

optimistic-concurrency ravendb event-sourcing

5
推荐指数
1
解决办法
680
查看次数