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字段中,并且没有向服务器发出请求。
是否有其他方法可以等待文档创建?
好吧,我不确定您使用的是什么机制来处理事件,但我在使用NServiceBus时也遇到过类似的情况。我不认为这是RavenDB的问题。如果您正在写入SQL Server数据库,则可能会遇到同样的问题。
广义问题是,Create
和Update
事件被触发,但它们的接收和处理顺序错误。该怎么办?
一般的建议是,您的事件处理程序应该是幂等的,并且应该在失败时重试。因此,如果首先接收到Update
,它将抛出异常并被安排重试。然后Create
通过,然后Update
重试,一切正常。
特别是不建议在Update
事件的处理程序中进行阻塞和等待,因为如果您有其中几个,那么它们可能会阻塞所有工作线程,而Create
事件永远不会通过。