2012-03-02 15 views
4

"WaitForNonStaleResults"のさまざまな味を使用しても、RavenDBが古くなっていることを確認したようです。完全機能サンプルコード(スタンドアローンテストとして書かれているので、コピー/ペーストしてそのまま実行できます)です。削除後にRavenDBが失効した結果を返す

public class Cart 
{ 
    public virtual string Email { get; set; } 
} 

[Test] 
public void StandaloneTestForPostingOnStackOverflow() 
{ 
    var testDocument = new Cart { Email = "[email protected]" }; 
    var documentStore = new EmbeddableDocumentStore { RunInMemory = true }; 
    documentStore.Initialize(); 

    using (var session = documentStore.OpenSession()) 
    { 
    using (var transaction = new TransactionScope()) 
    { 
     session.Store(testDocument); 
     session.SaveChanges(); 
     transaction.Complete(); 
    } 

    using (var transaction = new TransactionScope()) 
    { 
     var documentToDelete = session 
     .Query<Cart>() 
     .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) 
     .First(c => c.Email == testDocument.Email); 

     session.Delete(documentToDelete); 
     session.SaveChanges(); 
     transaction.Complete(); 
    } 

    RavenQueryStatistics statistics; 

    var actualCount = session 
     .Query<Cart>() 
     .Statistics(out statistics) 
     .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) 
     .Count(c => c.Email == testDocument.Email); 

    Assert.IsFalse(statistics.IsStale); 
    Assert.AreEqual(0, actualCount); 
    } 
} 

WaitForNonStaleResultsのすべてのフレーバーを試しましたが、変更はありません。期限切れでない結果を待つことは、アップデートでうまくいくようですが、削除ではうまくいかないようです。私が試してみました

更新

いくつかの点:

  1. アクションごとに別々のセッションを使用しました。結果:違いはありません。同じ成功と失敗。

  2. 最後のクエリの前にThread.Current.Sleep(500)を配置します。結果:成功。スレッドを0.5秒間スリープさせると、カウントはゼロのように戻ってきます。

+0

testDocumentはどこで宣言されていますか? documentToDeleteがnullではありませんか?セッションを閉じて新しいセッションでクエリを実行する必要がありますか? –

+0

testDocumentは、関数の最初の行で初期化されます。新しいセッションに関しては、現在のクエリ結果を取得するために新しいセッションを開く必要はありませんが、いずれにしても私はすでにそれを試しています。私は、追加情報の観測を含むように投稿を編集する。 –

+0

それは半分の睡眠が働くのは面白いです。私が考えることができる唯一のもう一つのことは、バグか、より良いインデックスが必要なことです。使用しているRavenDBのバージョンは何ですか? –

答えて

0

問題は削除に関連していないので、TransactionScopeを使用することに関連しています。ここでの問題は、DTCトランザクションが非同期で完了していることです。

session.Advanced.AllowNonAuthoritiveInformation = false; 

トランザクションが完了するのを待つためにRavenDBを強制します:

は、この問題を解決するには、何をする必要がある呼び出しです。

+1

この質問にご協力いただきありがとうございます。我々はそれを非常に感謝します!残念ながら、その行を追加しても問題は解決されませんでした。タイミングの間にまだ切断があります。 'ExecuteAllPendingLazyOperations'への呼び出しを追加しましたが、それは助けてくれることを期待していましたが、そうではありませんでした。私はトランザクションが非同期的に完了することを理解していますが、保留中のトランザクションが完了するまでリクエストを強制的に待つ方法はありますか?私はそれが 'WaitForNonStale ...'関数の目的だと思った。 –

+0

私はここでも逆の問題を抱えています。新しい文書ストア(完全に容認できない解決策)を初期化しない限り、私が何をしても結果は古くなってしまいます。何かが追加されたり削除されたりすると、それはうまくいきますが、更新されたものは、新しい文書ストアが作成されるまで更新が行われなかったかのように古いコンテンツを返します。これで3日を無駄にした... ... – nathanchere

1

Re:上記の私のコメントは古い結果で、AllowNonAuthoritiveInformationは機能しませんでした。この問題の通常の「答え」である各クエリにWaitForNonStaleResultsを配置する必要があるため、大量の「コードの匂い」のように感じられます(通常、ここでは嫌いですが、ここでは完全に適切です)。私がこれまでに見つけた

唯一の真の解決策は以下のとおりです。

var store = new DocumentStore(); // do whatever 
store.DatabaseCommands.DisableAllCaching(); 

パフォーマンスはそれに応じて苦しむが、私は遅くなり、性能が信頼できない場合はあからさまな不正確な結果よりも罪のはるかに少ないと思います。

1

これは古い質問ですが、私も最近この問題を横断しました。これは、それを作った私はすべてをカスタマイズする必要がないように

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite; 

:私はそれが最後の書き込みのような非古いのを待つ作るためにセッションで使用DocumentStore上の規約を変更することにより、それを回避することができましたクエリは後に実行されます。つまり、これはクエリに対してのみ機能すると私は信じています。私はテストを通して見つけたので、間違いなくパッチで動作しません。

私はこのことにも注意し、パフォーマンス上の問題を引き起こす可能性があるため、必要なコードの周りでのみ使用します。

session.DocumentStore.DefaultQueryingConsistency = ConsistencyOptions.None; 
関連する問題