我在 MS-SQL 数据库上使用实体框架。我正在实现一个 PUT Web 端点来更新“响应集”。
如果调用者指示 forceSave = true,即使 RowVersion 不匹配,我也想破坏记录。
这是我的代码,但它不起作用....
[HttpPut, Route("ResponseSets/{id:int}")]
public IHttpActionResult UpdateResponseSet(int id,
[FromBody] ResponseSet responseSetForUpdate,
[FromUri]bool? forceSave = false)
{
var db = new MyContext();
var responseSet = db.ResponseSets.FirstOrDefault(x => x.ResponseSetId == id);
if (!responseSet.RowVersion.SequenceEqual(responseSetForUpdate.RowVersion) && !forceSave.Value)
{
return new NegotiatedContentResult<LockingUser>(HttpStatusCode.Conflict,
new LockingUser(responseSet.LastUpdatedByUser), this);
}
responseSet.ResponseData = responseSetForUpdate.ResponseData;
responseSet.LastUpdatedByUser = HttpContext.Current.User.Identity.Name ?? "Anonymous";
responseSet.LastUpdatedDateTime = DateTime.Now;
db.SaveChanges();
return Ok();
}
大多数情况下它有效!但是,有时我会DBConcurrencyException
从SaveChanges()
. 我认为这是因为存在竞争条件。在我用另一个进程读取数据库之后FirstOrDefault
但在我用另一个进程写入数据库之前SaveChanges
可能会更新行并更改 RowVersion!有什么方法可以禁用RowVersion 检查?
我考虑过使用事务开始/结束,但显然这无济于事。
我想写一个循环,这样如果我得到 DBConcurrencyException,那么它会再次读取 RowVersion,并尝试再次写入......直到成功......但是天哪,感觉很糟糕。