2011-12-29 10 views
3

私は2つのアプリケーションのインスタンスを実行しています。 1つのインスタンスでは、私は自分のエンティティの1つを保存します。 RavenDB(http:// localhost:8080/raven)をチェックすると、私はその変更を見ることができます。次に、私の他のクライアントでは、これを行います(下記)が、他のアプリケーションからの変更は表示されません。 DBで最新のデータを取得するためには何が必要ですか?RavenDB - 1人のクライアントは別のクライアントからの変更を見ることができません

public IEnumerable<CustomVariableGroup> GetAll() 
{ 
    return Session 
     .Query<CustomVariableGroup>() 
     .Customize(x => x.WaitForNonStaleResults()); 
} 

編集:変更を加えて並行性の例外を取得しようとすると、上記のコードが機能します。その後、リフレッシュ(上記のコードを呼び出す)を呼び出すと、動作します。私ができるだけで、より詳細な情報といくつかのコードを欠く

public abstract class DataAccessLayerBase 
{ 
    /// <summary> 
    /// Gets the database. 
    /// </summary> 
    protected static DocumentStore Database { get; private set; } 

    /// <summary> 
    /// Gets the session. 
    /// </summary> 
    protected static IDocumentSession Session { get; private set; } 

    static DataAccessLayerBase() 
    { 
     if (Database != null) { return; } 

     Database = GetDatabase(); 
     Session = GetSession(); 
    }   

    private static DocumentStore GetDatabase() 
    { 
     string databaseUrl = ConfigurationManager.AppSettings["databaseUrl"];    

     DocumentStore documentStore = new DocumentStore(); 

     try 
     { 
      //documentStore.ConnectionStringName = "RavenDb"; // See app.config for why this is commented. 
      documentStore.Url = databaseUrl; 
      documentStore.Initialize(); 
     } 
     catch 
     { 
      documentStore.Dispose(); 
      throw; 
     } 

     return documentStore; 
    } 

    private static IDocumentSession GetSession() 
    { 
     IDocumentSession session = Database.OpenSession(); 

     session.Advanced.UseOptimisticConcurrency = true; 

     return session; 
    } 
} 

答えて

4

:ここ

public void Save<T>(T objectToSave) 
{ 
    Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave); 
    Session.Store(objectToSave, eTag); 
    Session.SaveChanges(); 
} 

とをデータベースとセッションを含むクラスである:ここでは

はセーブないコードがあります推測する...

セッションで.SaveChanges()に電話してください。 ITransactionを明示的に指定することなく、IDocumentSessionは分離され、開かれてから.SaveChangesへの呼び出しの間でトランザクションされます。すべての操作が成功するかどうか。しかし、あなたが以前に電話をしていなければ、.Storeの通話はすべて失われます。

私が間違っていた場合は、コードの詳細を投稿してください。


EDIT:(追加情報の後)第二の答え:

あなたの問題は、クライアント側のRavenDBは、キャッシュの方法に関係しています。 RavenDBはデフォルトで、DocumentSession全体のすべてのGET要求をキャッシュします。プレーンなクエリはGETクエリに過ぎません(また、動的であるか手動で定義されたインデックスを作成するために何もしていません)のでキャッシュされます。アプリケーションのソリューションは、セッションを破棄して新しいセッションを開くことです。

セッションのライフサイクルを再考することをお勧めします。セッションが長すぎると思われます。そうしないと、この並行性は問題にならないでしょう。 Webアプリケーションを構築する場合は、リクエストの開始時と終了時にセッションを開いて閉じることをお勧めします。 RaccoonBlogを見て、エレガントに実装されていることを確認してください。

+0

上記のコードをSave()に追加しました。それは役に立ちますか? –

+0

インデックスを追加していないことにも注意してください。 RavenDBが自動的にインデックスを追加したようです。手動で追加するのが古いかどうか、それともまだ適切かどうかはわかりません。 –

+0

Bob、手動でインデックスを追加する必要はありません。 RavenDBはクエリを評価し、あなたの質問(クエリ)に対する回答を提供する動的なインデックスを作成します。これらが頻繁に使用されると、RavenDBは自動的に最適化され、インデックスを永続化してディスクに保存します。非常に複雑なインデックスを手動で追加するだけで済みます。オリジナルの質問に答えるために上記の私の編集を見てください。 –

2

ボブ、 アプリケーションにセッションが1つしかないようですが、正しくありません。 NHibernateはについては、次の資料会談が、セッション管理部品だけでなくRavenDBに適用されます。

http://archive.msdn.microsoft.com/mag200912NHibernate

このコードは無意味です:

Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave); 
Session.Store(objectToSave, eTag); 

基本的にはそれがないOPが、重要になります1 。あなたは手動ですべてのセーブを管理しなければならないモデルで作業しようとしているようですが、そうしないでください。新しいアイテムを作成するときは、自分だけを管理する必要があります。それだけです。あなたはこの問題を取得した理由については

、ここでのサンプルは次のとおりです。

var session = documentStore.OpenSession(); 
var post1 = session.Load<Post>(1); 
// change the post by another client 
post2 = session.Load<Post>(1); // will NOT go to the server, will give the same instance as post1 

Assert.ReferenceEquals(post1,post2); 

セッションは短命、そして一般的に単一のフォーム/リクエストの範囲で使用されています。

+0

さて、私はそのリンクを今読んでいます。セッションが短期間で、単一のフォームの範囲内にある場合、フォームがアプリケーションの全期間にわたって開いている場合はどうなりますか?実際、ユーザーがこのUIダッシュボードユーティリティを開くと、そのすべてがアプリにあります。データを管理するフォーム/ウィンドウ。だから、メソッドがセッションの生涯にあまりにも短すぎると、アプリケーション全体が長すぎる場合は...ご存知ですか?さて、そのリンクが役立つかどうかがわかります。ヘルプをよろしくお願いいたします。 –

+0

ボブ、それはNHibernatesセッションまたはEntity Frameworks ObjectContextと全く同じです。そこにも同じルールが適用されます。予想されるキャッシュの問題により寿命が短くなる場合は、フォームを頻繁に再作成するだけです。それは簡単です。 –

関連する問題