使用Raven客户端和服务器#30155。我基本上在控制器中执行以下操作:
public ActionResult Update(string id, EditModel model)
{
var store = provider.StartTransaction(false);
var document = store.Load<T>(id);
model.UpdateEntity(document) // overwrite document property values with those of edit model.
document.Update(store); // tell document to update itself if it passes some conflict checking
}
然后在document.Update中,我尝试这样做:
var old = store.Load<T>(this.Id);
if (old.Date != this.Date)
{
// Resolve conflicts that occur by moving document period
}
store.Update(this);
现在,我遇到了old
加载内存而不是数据库并且已经包含更新值的问题。因此,它永远不会进入冲突检查。
我尝试通过将Controller.Update
方法更改为:
public ActionResult Update(string id, EditModel model)
{
var store = provider.StartTransaction(false);
var document = store.Load<T>(id);
store.Dispose();
model.UpdateEntity(document) // overwrite document property values with those of edit model.
store = provider.StartTransaction(false);
document.Update(store); // tell document to update itself if it passes some conflict checking
}
这导致我获得Raven.Client.Exceptions.NonUniqueObjectException
文字Attempted to associate a different object with id
现在,问题:
如果我尝试将新对象与id相关联,为什么Raven会关心,只要新对象带有正确的电子标签并输入?
是否可以在其数据库状态下加载文档(如果存在,则覆盖默认行为以从内存中获取文档)?
让document.Update()
工作的最佳解决方案是什么(最好不必传递旧对象)?
答案 0 :(得分:0)
RavenDB倾向于能够从内存中提供文档(速度更快)。通过检查相同id的持久对象,可以防止难以调试的错误。
编辑:请参阅以下Rayen的评论。如果在Store中启用并发检查/提供etag,则可以绕过错误。
显然不是。
我去重构document.Update方法也有一个可选参数来接收旧日期,因为#1和#2似乎不可能。
答案 1 :(得分:-1)
RavenDB支持开箱即用的乐观并发。你唯一需要做的就是打电话。
session.Advanced.UseOptimisticConcurrency = true;