2011-12-29 5 views
2

Есть ли способ установить оптимистичный параллелизм в true в Raven.Server.exe.config? Или может ли это как-то применяться на уровне базы данных? На сайте RavenDB, я вижу несколько упоминаний о настройке UseOptimisticConcurrency = верно, но это выглядит, как будто это на уровне сеанса в коде:RavenDB UseOptimisticConcurrency в конфигурации?

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

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

ответ

1

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

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

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

+0

Необходимо ли сохранить объект в том же сеансе, в который он был загружен/запрошен? И я не вижу, где эта ссылка отображает информацию об управлении сеансом. –

+0

Кстати, я нашел это. Возможно, это похоже на ссылку, которую вы опубликовали: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx –

1

Отказ от ответственности: Это не рекомендуемый подход, а на самом деле неправильная практика - открыть IDocumentSession, который будет жить до тех пор, пока клиентское приложение будет жить. Для альтернативного решения см. Ответ, размещенный здесь: RavenDB Catch 22 - Optimistic Concurrency AND Seeing Changes from Other Clients.

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

Во-первых, в 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(); 
    } 
} 

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

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

+0

Боб, не могли бы вы отредактировать этот ответ и пояснить, что не рекомендуется и на самом деле плохой практике открывать IDocumentSession, который будет жить до тех пор, пока клиентское приложение будет жить. Это может вызвать некоторую путаницу, когда другие читают это. Благодарю. –

+0

Даниэль, я не против даже его удаления. Я смог сделать то, что мне здесь нужно: http://stackoverflow.com/questions/8675958/ravendb-catch-22-optimistic-concurrency-and-seeing-changes-from-other-clients –

+0

Да, я знаю. Вот почему я попросил вас отредактировать этот пост, чтобы другим не нужно было следовать одному и тому же пути. Я бы не рекомендовал удалить его, потому что он может обеспечить ценность для других. Просто поставьте заявление об отказе и ссылку на него, и все будет хорошо, я думаю :) –