当我们拥有特定唯一的实体ID时,事件溯源(EventSourcing)可以完美运作。但是当我尝试从事件存储(EventStore)中获取特定实体ID以外的信息时,我遇到了困难。
我正在使用带有事件溯源的CQRS(Command Query Responsibility Segregation)。作为事件溯源的一部分,我们将事件作为列(EntityID(唯一键),EventType,EventObject(例如UserAdded))存储在SQL表中。
因此,在存储EventObject时,我们只需对DotNet对象进行序列化并将其存储在SQL中,因此,与UserAdded事件相关的所有详细信息都将以xml格式存在。我的问题是,我想确保数据库中存在的userName应该是唯一的。
所以,在创建AddUser命令时,我必须查询EventStore(sql db)以确定特定的用户名是否已经存在于eventStore中。 因此,为了做到这一点,我需要序列化存储在事件存储中的所有UserAdded / UserEdited事件,并检查请求的用户名是否存在于eventStore中。
但作为CQRS的一部分,命令不允许查询,可能是由于竞争条件。
因此,在发送AddUser命令之前,我尝试查询事件存储并通过序列化所有事件(UserAdded)来获取所有UserNames,并获取用户名。如果请求的用户名是唯一的,则发送命令,否则抛出异常,说明用户名已经存在。
通过以上方法,我们需要查询整个数据库,而且每天可能会有成千上万的事件。因此,查询/反序列化的执行时间将变得很长,从而导致性能问题。
我正在寻找维护唯一用户名的任何更好方法/建议,无论是通过从eventStore获取所有用户名还是通过其他方法。
IKeyStore
接口:https://github.com/Shuttle/shuttle-recall-core/blob/master/Shuttle.Recall.Core/IKeyStore.cs,您可以在这里看到实现:https://github.com/Shuttle/shuttle-recall-sqlserver/blob/master/Shuttle.Recall.SqlServer/KeyStore.cs --- 任意键的哈希与AR id相关联。希望这可以帮助 :) - Eben Roux