RavenDB-等待文档创建

本文关键字:创建 文档 等待 RavenDB- | 更新日期: 2023-09-27 18:25:18

我使用RavenDB作为从域事件填充的非规范化读取模型。我发现问题是,当两个事件(我们称之为Created和Updated)同时被取消规范化时,在保存Created事件所做的更改之前,加载要由Updated事件更新的文档。我已经想出了一个基于Changes API的解决方案来等待文档创建:

public static T WaitAndLoad<T>(this IDocumentSession @this, ValueType id)
        where T : class
    {
        var fullId = @this.Advanced.DocumentStore.Conventions.FindFullDocumentKeyFromNonStringIdentifier(id, typeof(T), false);
        var ev = new ManualResetEvent(false);
        var cancelation = new CancellationTokenSource();
        @this.Advanced.DocumentStore
             .Changes()
             .ForDocument(fullId)
             .Subscribe(change =>
                 {
                     if (change.Type == DocumentChangeTypes.Put)
                     {
                         ev.Set();
                     }
                 }, cancelation.Token);

        try
        {
            var existing = @this.Load<T>(id);
            if (existing != null)
            {
                return existing;
            }
            ev.WaitOne();
            return @this.Load<T>(id);
        }
        finally
        {
            cancelation.Cancel();
        }            
    }

不幸的是,对Load的第二次调用返回null,因为文档的Id已经在InMemoryDocumentSessionOperations的knownMissingIds字段中,并且没有向服务器发出请求。

是否有其他方法可以等待文档创建?

RavenDB-等待文档创建

好吧,我不确定您使用的是什么机制来处理事件,但我在使用NServiceBus时也遇到过类似的情况。我不认为这是RavenDB的问题。如果您正在写入SQL Server数据库,则可能会遇到同样的问题。

广义问题是,CreateUpdate事件被触发,但它们的接收和处理顺序错误。该怎么办?

一般的建议是,您的事件处理程序应该是幂等的,并且应该在失败时重试。因此,如果首先接收到Update,它将抛出异常并被安排重试。然后Create通过,然后Update重试,一切正常。

特别是不建议在Update事件的处理程序中进行阻塞和等待,因为如果您有其中几个,那么它们可能会阻塞所有工作线程,而Create事件永远不会通过。