RavenDB是否在配置中使用OptimisticConcurrency?

RavenDB是否在配置中使用OptimisticConcurrency?,ravendb,optimistic-locking,optimistic-concurrency,Ravendb,Optimistic Locking,Optimistic Concurrency,有没有办法在Raven.Server.exe.config中将乐观并发设置为true?或者,它能以某种方式应用于数据库级别吗?在RavenDB的网站上,我看到了一些关于设置UseOptimisticConcurrency=true的内容,但它看起来像是在代码中的会话级别: public void Save<T>(T objectToSave) { using (IDocumentSession session = Database.OpenSession()) {

有没有办法在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();
    }
}
public void保存(T objectToSave)
{
使用(IDocumentSession session=Database.OpenSession())
{
session.Advanced.UseOptimisticConcurrency=true;//这是设置
Guid eTag=(Guid)session.Advanced.GetEtagFor(objectToSave);
session.Store(objectToSave,eTag);
session.SaveChanges();
}
}
我想知道这个设置是否存在于服务器范围内的某个地方,所以不需要在代码中为每个会话指定它

编辑:上面的代码产生以下错误。试图找出原因


编辑2:好的,我正在进步。如果在同一个会话中检索对象并调用GetEtagFor(),则会得到一个有效的eTag。所以我想我现在的主要问题是:在客户端UI中使用会话,在应用程序启动时打开会话一次,然后在最后关闭会话,这是正确的方法吗?而且。。。存储eTag的正确方法是什么?按照上面的编码方式,eTag在存储之前就被检索,我认为这是一种错误的方式。我猜应该在第一次检索对象时检索eTag。但是,当我们最初得到一个对象列表时,我们是否应该遍历每个对象并对它们调用GetEtagFor()?似乎不正确…

免责声明:这不是一种推荐的方法,事实上,打开IDocumentSession的做法很糟糕,它将与客户端应用程序的寿命一样长。有关替代解决方案,请参见此处发布的答案:

看起来我得到了乐观的并发工作,所以我想我应该发布这个来帮助其他人

首先,在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>();
    }
}
公共类CustomVariableGroupData:DataAccessLayerBase,ICustomVariableGroupData
{
公共IEnumerable GetAll()
{
返回Session.Query();
}
}
最后,保存时,获取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();
    }
}
公共类GenericData:DataAccessLayerBase、IGenericData
{
公共作废保存(T objectToSave)
{
Guid eTag=(Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave,eTag);
Session.SaveChanges();
}
}
如果UI的另一个实例正在运行,并且更改了对象,则会发生并发异常。这就是我们想要的

我又看了一遍这篇文章的标题,意识到这并不能回答如何在服务器配置文件中设置并发性的问题。但是,由于现在可以在数据层设置一次,这对我来说已经足够了。

Bob, 不,UseOptimisticConcurrency是打开会话时需要设置的内容。 不,在整个应用程序中使用单个会话是错误的。有关会话管理的更多详细信息,请参阅本文:


它谈到了NHibernate,但会话管理部分也适用于ravendb。

是否需要在加载/查询对象的同一会话中保存该对象?我看不到这个链接在哪里显示会话管理的信息。顺便说一下,我找到了这个。也许这与您发布的链接类似:Bob,请您编辑此答案,并明确指出,不建议打开与客户端应用程序寿命相同的IDocumentSession,事实上这是一种糟糕的做法。这可能会给其他阅读本文的人带来一些困惑。谢谢。丹尼尔,我甚至不介意删除它。我在这里能做我需要的事情:是的,我知道。这就是为什么我要求你编辑这篇文章,这样其他人就不需要遵循同样的路径。我不建议删除它,因为它可能为其他人提供价值。只要在上面放一个免责声明和一个链接,我想就可以了:)