RavenDB Catch 22-乐观并发性,并看到其他客户端的变化 [英] RavenDB Catch 22 - Optimistic Concurrency AND Seeing Changes from Other Clients
问题描述
使用RavenDB,在应用程序启动时创建一个IDocumentSession
(并且直到应用程序关闭后才关闭它),这使我可以使用开放式并发:
With RavenDB, creating an IDocumentSession
upon app start-up (and never closing it until the app is closed), allows me to use optimistic concurrency by doing this:
public class GenericData : DataAccessLayerBase, IGenericData
{
public void Save<T>(T objectToSave)
{
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
Session.SaveChanges();
}
}
如果另一个用户更改了该对象,则保存将正确失败.
If another user has changed that object, then the save will correctly fail.
但是,当在应用程序的整个生命周期中使用一个会话时,我无法做的是看到该应用程序的其他实例(例如,乔,相隔五个小隔间)对文档所做的更改.当我这样做时,我看不到乔的变化:
But what I can't do, when using one session for the lifetime of an app, is seeing changes, made by other instances of the app (say, Joe, five cubicles away), to documents. When I do this, I don't see Joe's changes:
public class CustomVariableGroupData : DataAccessLayerBase, ICustomVariableGroupData
{
public IEnumerable<CustomVariableGroup> GetAll()
{
return Session.Query<CustomVariableGroup>();
}
}
注意:我也尝试过这样做,但是它也没有显示Joe的更改:
Note: I've also tried this, but it didn't display Joe's changes either:
return Session.Query<CustomVariableGroup>().Customize(x => x.WaitForNonStaleResults());
现在,如果我走另一条路,并且在访问数据库的每个方法中都创建一个IDocumentSession
,那么我遇到了相反的问题.因为我有一个新的会话,所以我可以看到Joe的更改. Buuuuuuut ...然后我失去了乐观的并发性.当我在保存之前创建新会话时,此行会生成一个空的GUID,因此会失败:
Now, if I go the other way, and create an IDocumentSession
within every method that accesses the database, then I have the opposite problem. Because I have a new session, I can see Joe's changes. Buuuuuuut... then I lose optimistic concurrency. When I create a new session before saving, this line produces an empty GUID, and therefore fails:
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
我想念什么?如果不应该在每种方法中都不在应用程序级别中创建会话,那么正确的范围是什么?在执行Session.Query()时,如何获得乐观并发和的好处?
What am I missing? If a Session shouldn't be created within each method, nor at the app level, then what is the correct scope? How can I get the benefits of optimistic concurrency and the ability to see others' changes when doing a Session.Query()?
推荐答案
免责声明:我知道这不是长期的方法,因此在这里不会被接受.但是,我只需要现在就可以工作,以后就可以重构了.我也知道有些人会对这种方法感到厌恶,哈哈,但是就这样吧.它似乎正在工作.我在每个查询(新会话)中都获得了新数据,并且乐观并发也可以正常工作.
Disclaimer: I know this can't be the long-term approach, and therefore won't be an accepted answer here. However, I simply need to get something working now, and I can refactor later. I also know some folks will be disgusted with this approach, lol, but so be it. It seems to be working. I get new data with every query (new session), and I get optimistic concurrency working as well.
最重要的是,我每种数据访问方法都返回到一个会话.每当数据访问方法执行某种类型的获取/加载/查询时,我都会将eTag存储在静态字典中:
The bottom line is that I went back to one session per data access method. And whenever a data access method does some type of get/load/query, I store the eTags in a static dictionary:
public IEnumerable<CustomVariableGroup> GetAll()
{
using (IDocumentSession session = Database.OpenSession())
{
IEnumerable<CustomVariableGroup> groups = session.Query<CustomVariableGroup>();
CacheEtags(groups, session);
return groups;
}
}
然后,当我保存数据时,我从缓存中获取了eTag.如果另一个实例修改了数据,这将导致并发异常.
Then, when I'm saving data, I grab the eTag from the cache. This causes a concurrency exception if another instance has modified the data, which is what I want.
public void Save(EntityBase objectToSave)
{
if (objectToSave == null) { throw new ArgumentNullException("objectToSave"); }
Guid eTag = Guid.Empty;
if (objectToSave.Id != null)
{
eTag = RetrieveEtagFromCache(objectToSave);
}
using (IDocumentSession session = Database.OpenSession())
{
session.Advanced.UseOptimisticConcurrency = true;
session.Store(objectToSave, eTag);
session.SaveChanges();
CacheEtag(objectToSave, session); // We have a new eTag after saving.
}
}
从长远来看,我绝对想以正确的方式来做,但是我不知道那是什么方式.
I absolutely want to do this the right way in the long run, but I don't know what that way is yet.
在我找到更好的方法之前,我将把它作为公认的答案.
I'm going to make this the accepted answer until I find a better way.
这篇关于RavenDB Catch 22-乐观并发性,并看到其他客户端的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!