RavenDB Использовать OptimisticConcurrency в Config? - PullRequest
2 голосов
/ 29 декабря 2011

Есть ли способ установить оптимистичный параллелизм в true в Raven.Server.exe.config?Или это можно как-то применить на уровне базы данных?На сайте 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();
    }
}

Я хотел бы знать, существует ли этот параметр где-нибудь на сервере-в целом, поэтому его не нужно указывать для каждого сеанса в коде.

Редактировать: приведенный выше код вызывает следующую ошибку.Попытка выяснить, почему ...

enter image description here

Редактировать 2: Хорошо, я делаю успехи.Если я получу объект и вызову GetEtagFor () для всех в пределах одного сеанса , я получу действительный eTag.Итак, я предполагаю, что мой главный вопрос сейчас таков: является ли правильный способ использовать сеанс в пользовательском интерфейсе клиента, чтобы один раз открыть сеанс при запуске приложения, а затем закрыть его в конце?И ... Как правильно хранить eTag?Как написано выше, eTag извлекается непосредственно перед сохранением, что, я думаю, является неправильным способом сделать это.Я предполагаю, что eTag должен быть получен при первом получении объекта.Но когда мы первоначально получаем список объектов, должны ли мы пройти через каждый из них и вызвать GetEtagFor () для них?Не кажется правильным ...

Ответы [ 2 ]

1 голос
/ 30 декабря 2011

Боб, Нет, UseOptimisticConcurrency - это то, что вам нужно настроить при открытии сеанса.И НЕТ, один сеанс для всего приложения - неправильная вещь.См. Эту статью для более подробной информации об управлении сессиями:

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

В нем говорится о NHibernate, но части управления сессиями применимы и к ravendb.

1 голос
/ 29 декабря 2011

Отказ от ответственности: это не рекомендуемый подход, и на самом деле это плохая практика - открывать IDocumentSession, который будет существовать столько же, сколько и клиентское приложение.Альтернативное решение см. В ответе, опубликованном здесь: RavenDB Catch 22 - оптимистичный параллелизм и просмотр изменений от других клиентов .

Похоже, у меня работает оптимистичный параллелизм, поэтому я подумал:Публикуйте это, чтобы помочь кому-либо еще.

Сначала в 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();
    }
}

Если другой экземпляр пользовательского интерфейса работает и изменяет объект, возникнет исключение параллелизма.И это то, что мы хотели.

Я просто снова посмотрел на заголовок этого поста и понял, что это не отвечает на вопрос о том, как установить параллелизм в конфигурационном файле сервера.Однако, поскольку теперь он может быть установлен один раз в слое данных, для меня этого достаточно.

...