RavenDB - 解决冲突后的空引用异常?

时间:2015-06-10 19:05:45

标签: ravendb database-replication

我们在Azure VM上运行两个Raven服务器,这些服务器彼此复制。偶尔,我们会遇到复制冲突。我们有一个冲突侦听器,它可以在文档的两个版本的内容相同的情况下自动解决冲突。我们还在两台机器上运行脚本,检查冲突并报告它们。

我们今天在以下某个服务器中发生了错误,其中包含以下堆栈跟踪:

Raven.Client.Connection.ServerClient.<DirectQuery>b__77(String conflictedResultId):0
 Raven.Client.Connection.ServerClient.AssertNonConflictedDocumentAndCheckIfNeedToReload(RavenJObject docResult, Func`2 onConflictedQueryResult):110
 Raven.Client.Connection.ServerClient+<>c__DisplayClass94`1.<RetryOperationBecauseOfConflict>b__93(Boolean current, RavenJObject docResult):0
 System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable`1 source, TAccumulate seed, Func`3 func):46
 Raven.Client.Connection.ServerClient.RetryOperationBecauseOfConflict[T](IEnumerable`1 docResults, T currentResult, Func`1 nextTry, Func`2 onConflictedQueryResult):35
 Raven.Client.Connection.ServerClient.DirectQuery(String index, IndexQuery query, OperationMetadata operationMetadata, String[] includes, Boolean metadataOnly, Boolean includeEntries):579
 Raven.Client.Connection.ServerClient+<>c__DisplayClass62.<Query>b__61(OperationMetadata u):0
 Raven.Client.Connection.ReplicationInformer.TryOperation[T](Func`2 operation, OperationMetadata operationMetadata, OperationMetadata primaryOperationMetadata, Boolean avoidThrowing, T& result, Boolean& wasTimeout):200
 Raven.Client.Connection.ReplicationInformer.ExecuteWithReplication[T](String method, String primaryUrl, OperationCredentials primaryCredentials, Int32 currentRequest, Int32 currentReadStripingBase, Func`2 operation):193
 Raven.Client.Connection.ServerClient.ExecuteWithReplication[T](String method, Func`2 operation):44
 Raven.Client.Document.AbstractDocumentQuery`2.ExecuteActualQuery():65
 Raven.Client.Document.AbstractDocumentQuery`2.get_QueryResult():6
 Raven.Client.Linq.RavenQueryProviderProcessor`1.ExecuteQuery[TProjection]():123
 Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator():0

在针对其中一个集合的Lucene查询期间发生异常。堆栈跟踪表明遇到了冲突。对AssertNonConflictedAndCheckIfNeedToReload的呼吁表明冲突得到了解决。目前机器上没有冲突,团队也没有手动解决任何冲突,所以我认为它是由冲突听众处理的。

有没有人知道可能导致空引用异常的原因是什么?

编辑:这是冲突侦听器的代码。除了名为UtcTimestamp的字段外,它会检查两个版本是否相同。如果是,则使用最新版本解析。

if (conflictedDocs.Length < 2)
{
   // This really, really shouldn't happen
   resolvedDocument = null;
   return false;
}

string previousDocument = string.Empty;

int counter = 0;

foreach (var conflictedDoc in conflictedDocs)
{
    // We don't want the comparison of document versions to look at a property called UtcTimestamp
    conflictedDoc.DataAsJson.Remove("UtcTimestamp");
    var alteredConflictedDocString = conflictedDoc.DataAsJson.ToString();

    if (counter > 0)
    {
       if (previousDocument != alteredConflictedDocString)
       {
           resolvedDocument = null;
           return false;
       }
    }

    previousDocument = alteredConflictedDocString;
    counter++;
 }

 resolvedDocument = conflictedDocs.OrderByDescending(x => x.LastModified).First();

 ConflictHelper.RemoveBadMetadata(resolvedDocument);

 return true;

ConflictHelper.RemoveBadMetadata()执行此操作:

if (documentToResolveWith.Metadata.ContainsKey("@id"))
{
     documentToResolveWith.Metadata.Remove("@id");
}

if (documentToResolveWith.Metadata.ContainsKey("@etag"))
{
     documentToResolveWith.Metadata.Remove("@etag");
}

if (documentToResolveWith.Metadata.ContainsKey("Raven-Replication-Conflict-Document"))
{
     documentToResolveWith.Metadata.Remove("Raven-Replication-Conflict-Document");
}

0 个答案:

没有答案