2

Raven.Server.exe.configで楽観的同時実行性をtrueに設定する方法はありますか?または、データベースレベルで何らかの形で適用できますか?RavenDBのサイトで、UseOptimisticConcurrency = trueの設定についていくつか言及されていますが、コード内のセッションレベルにあるように見えます。

public void Save<T>(T objectToSave)
{
    using (IDocumentSession session = Database.OpenSession())
    {
        session.Advanced.UseOptimisticConcurrency = true;  // This is the setting
        Guid eTag = (Guid)session.Advanced.GetEtagFor(objectToSave);
        session.Store(objectToSave, eTag);
        session.SaveChanges();
    }
}

その設定がサーバー全体のどこかに存在するかどうかを知りたいので、コードでセッションごとに指定する必要はありません。

編集:上記のコードは次のエラーを生成します。理由を見つけようとしています...

ここに画像の説明を入力してください

編集2:わかりました、私は進歩しています。オブジェクトを取得し、すべて同じセッション内でGetEtagFor()を呼び出すと、有効なeTagが取得されます。ですから、私の主な質問は次のとおりです。クライアントUI内でセッションを使用して、アプリの起動時にセッションを1回開き、最後に閉じる方法は正しいですか。そして...eTagを保存する正しい方法は何ですか?上でコーディングした方法では、eTagは保存する直前に取得されますが、これは間違った方法だと思います。オブジェクトが最初に取得されたときにeTagを取得する必要があると思います。しかし、最初にオブジェクトのリストを取得するとき、それぞれをループして、それらに対してGetEtagFor()を呼び出す必要がありますか?正しくないようです...

4

2 に答える 2

1

ボブ、いいえ、UseOptimisticConcurrencyは、セッションを開くときに設定する必要があるものです。いいえ、アプリケーション全体で1つのセッションを実行するのは間違っています。セッション管理の詳細については、次の記事を参照してください。

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

NHibernateについて説明していますが、セッション管理の部分はravendbにも適用されます。

于 2011-12-30T09:08:36.367 に答える
1

免責事項:これは推奨されるアプローチではありません。実際、クライアントアプリが存続する限り存続するIDocumentSessionを開くことはお勧めできません。別の解決策については、ここに投稿された回答を参照してください:RavenDBCatch22-楽観的同時実行性および他のクライアントからの変更の確認

楽観的並行性が機能しているように見えるので、他の人を助けるためにこれを投稿したいと思いました。

まず、DataAccessLayerBaseで、DocumentStoreとIDocumentSessionを初期化します。これらは、クライアントアプリが実行されている限り開いて使用されます。

public abstract class DataAccessLayerBase
{
    protected static DocumentStore Database { get; private set; }

    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.Url = databaseUrl;
            documentStore.Initialize();
        }
        catch
        {
            documentStore.Dispose();
            throw;
        }

        return documentStore;
    }

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

        session.Advanced.UseOptimisticConcurrency = true;

        return session;
    }
}

次に、データを取得するときに、既存のセッションを使用します。

public class CustomVariableGroupData : DataAccessLayerBase, ICustomVariableGroupData
{
    public IEnumerable<CustomVariableGroup> GetAll()
    {
        return Session.Query<CustomVariableGroup>();
    }
}

最後に、保存するときに、eTagを取得して保存します。

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

UIの別のインスタンスが実行されていて、オブジェクトを変更すると、同時実行例外が発生します。そしてそれが私たちが望んでいたことです。

この投稿のタイトルをもう一度見たところ、サーバー構成ファイルで同時実行性を設定する方法の質問に答えられないことがわかりました。ただし、データレイヤーで一度設定できるようになったので、それで十分です。

于 2011-12-29T15:38:48.903 に答える