c# - 查询重复聚合根属性的写入模型

标签 c# nservicebus cqrs event-sourcing neventstore

我正在使用事件源实现 CQRS 模式,我正在使用 NServiceBus、NEventStore 和 NES(NSB 和 NEventStore 之间的连接)。

我的应用程序将定期检查 Web 服务以查找要下载和处理的任何文件。当找到一个文件时,一个命令 (DownloadFile) 被发送到总线,并由 FileCommandHandler 接收,它创建一个新的聚合根 (File) 并处理消息。

现在在(文件聚合根)中,我必须检查文件的内容是否与任何其他文件内容不匹配(因为网络服务保证只有文件名是唯一的,并且内容可能与不同的名称),通过对其进行散列并与散列内容列表进行比较。

问题是我必须在哪里保存哈希码列表?是否允许查询读取模型?

public class File : AggregateBase
{
    public File(DownloadFile cmd, IFileService fileDownloadService, IClaimSerializerService serializerService, IBus bus)
            : this()
        {
        // code to download the file content, deserialize it, and publish an event.
        }
}

public class FileCommandHandler : IHandleMessages<DownloadFile>, IHandleMessages<ExtractFile>
{
        public void Handle(DownloadFile command)
        {
             //for example, is it possible to do this (honestly, I feel it is not, since read model should always considered stale !)
            var file = readModelContext.GetFileByHashCode (Hash(command.FileContent));
            if (file != null)
                throw new Exception ("File content matched with another already downloaded file");

            // Since there is no way to query the event source for file content like:
            // eventSourceRepository.Find<File>(c=>c.HashCode == Hash(command.FileContent));
        }
}

最佳答案

您似乎在寻找重复数据删除。

您的命令端是您希望事情保持一致的地方。查询总是会让你面临竞争条件。因此,我不运行查询,而是反转逻辑并将哈希实际写入数据库表(任何具有 ACID 保证的数据库)。如果写入成功,则处理该文件。如果哈希写入失败,则跳过处理。

将此逻辑放入处理程序是没有意义的,因为在失败的情况下重试消息(即多次存储哈希)不会使其成功。您最终还会在错误 q 中收到有关重复文件的消息。

重复数据删除逻辑的一个好地方可能在您的 Web 服务客户端中。一些伪逻辑

  1. 获取文件
  2. 开启交易
  3. 将哈希插入数据库并捕获失败(不是任何失败,只是插入失败)
  4. 如果在步骤 3 中插入​​的记录数不为零,则 Bus.Send 消息到进程文件
  5. 提交交易

NServiceBus 网关中的一些重复数据删除代码示例 here

编辑:
查看他们的代码,我实际上认为 session.Get<DeduplicationMessage>是不必要的。 session.Save(gatewayMessage);应该足够了,并且是一致性边界。

只有在失败率很高的情况下进行查询才有意义,这意味着您有很多重复的内容文件。如果 99%+ 的插入成功,重复项确实可以被视为异常。

关于c# - 查询重复聚合根属性的写入模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23215983/

相关文章:

c# - C#中的别名资源文件命名空间

c# - 在 ASP.NET MVC (C#) 中通过 Amazon SNS 配置 Amazon SES 反馈通知

c# - 尝试将 Google Analytics 连接到我们的应用程序时出现 "You should avoid this app"

.net - 将 NServiceBus 与多个应用程序一起使用,同时充当发布者和订阅者

c# - NServiceBus - 基于内容的路由和审计 - 我的方法可以吗?

.net - NServiceBus 行为的作用域依赖使用

c# - 使用 CQRS/事件溯源时,事件是否应该按顺序存储以及如何存储

c# - c# 定时器自然是多线程的吗?

azure - 我是否使用 Azure 表存储或 SQL Azure 作为我们的 CQRS 读取系统?

elasticsearch - CQRS(Lagom)elasticsearch读取侧