事件源和同步读取。有可能吗?

时间:2019-01-24 23:59:45

标签: asynchronous synchronization event-sourcing eventual-consistency

在网上找不到任何确定的答案。我想在项目中使用ES,但令我感到困扰的是它的异步特性。 考虑一个协作性博客网站(为了简化起见,我在编造东西,因为我的领域要复杂得多)。 用户可以创建博客文章并进行编辑。就是这样,仅此而已。 所以,我刚刚用

创建了一个博客条目
createBlogEntryCommand = new CreateBlogEntryCommand(body, tags)
createBlogEntryCommand.execute()

使用ES我将BlogEntryCreatedEvent存储在ES商店中,类似

eventStore.append({
    "id": "1d11071c-33c6-4621-bb86-cafcc3ca23a6",
    "body": "Lorem ipsum dolor sit amet....",
    "tags": ["awesome-reading", "awesome-writing"],
})

现在,我不知道消费者何时会选择并处理此事件。当然,我可以使用启发式度量标准,并保证在某种程度上可以在X毫秒内处理此事件,但是例如,如果使用者需要维护,该怎么办?如何使博客条目立即可供作者使用?

果然,我可以在数据库中查询1d11071c-33c6-4621-bb86-cafcc3ca23a6的博客ID(因为它是预先生成的,因此发布ID并不是数据库问题),一旦使用者选择了事件并在数据库中创建了实例化视图,使其对用户可用,但是 这是唯一的方法 吗?

  

P.S。我在线上观看了很多有关该主题的视频,我也阅读了大量的博客,但是任何消息似乎都在绕开ES的警告,但没有解释任何方法。多数情况下,我听到的答案是“可以在UI / UX级别解决”。因此,如果有好的书籍/文章/视频正在详细讨论如何克服ES陷阱,请分享评论。

更新

立即阅读同步历史...实际上我想到了这个,但是很快就拒绝了这个想法。 考虑到一个简单的待办事项应用程序,用户可以在其中注册并创建待办事项列表,我设想拥有类似的

  

UserRegistered

     

TodoCreated

     

TodoUpdated

     

TodoCompleted

     

TodoDeleted

     

TodoUnDeleted

从事件存储中读取事件时,我对其他用户的待办事项不感兴趣,但仅对当前用户的待办事项感兴趣。这意味着要存储如下事件:

  

UserRegistered (用户名:Bob,ID:1}

     

UserRegistered {name:Alice,id:2}

     

TodoCreated {id:123,待办事项:购买牛奶,用户:1}

     

TodoUpdated ({id:123,待办事项:购买脱脂牛奶,用户:1}

)      

TodoCompleted {id:123}

     

TodoCreated {id:456,todo:支付会费,用户:2}

     

TodoCompleted {id:456}

     

TodoDeleted {id:123}

     

TodoUnDeleted {id:123}

     

TodoUpdated ({id:123,待办事项:购买全脂牛奶!,用户:1}

如果需要我获取Bob的待办事项ID 123(购买牛奶)的最新状态,尽管它们可能与Bob的项目列表无关,但我仍需要阅读所有事件。因此,我将遍历其他用户(除了Bob之外)创建的待办事项事件堆,以仅过滤并应用Bob的事件。

这是否意味着我将被要求在事件存储区中具有特殊的“渠道”,以仅包含Bob对待办事项的操作。 此外,如果其他人能够管理Bob的待办事项清单项目,该怎么办?如果爱丽丝有权修改鲍勃的待办事项怎么办?会不会大大增加事件存储架构?

1 个答案:

答案 0 :(得分:1)

  

这是唯一的方法吗?

否。

从事件存储中读取事件的历史记录,然后使用这些事件来按需计算视图,这没有错。

View v = View.from(events);
  

这是否意味着我将被要求在事件存储区中具有特殊的“渠道”,以仅包含Bob对待办事项的操作。此外,如果其他人能够管理Bob的待办事项清单项目,该怎么办?如果爱丽丝有权修改鲍勃的待办事项怎么办?会不会大大增加事件存储架构?

通常的答案是,属于在一起的事件将共享一个关联ID,并且消息存储库允许您指定要使用的密钥。

例如,如果您使用RDBMS作为存储,则可能对所有事件数据都有一个blob列,然后再有许多其他列来存储对检索有用的元数据位。 / p>

访问规则(可以进行更改的对象)与事件本身(事件相关的对象)的上下文是一个单独的问题。