[英]ASP.NET | Entity Framework, race condition
我有一个Web应用程序,允许用户喜欢的项目。 每件物品都有他喜欢的总物品。
当许多用户同时喜欢同一个项目时会出现问题,然后我在SQL中收到错误的值(由竞争条件引起)。
作为一个临时解决方案,我在控制器构造函数中创建了一个工作线程,它对一个队列起作用,当一个像/不喜欢请求的项目正在接收时,我正在排队这个请求。 工作线程正在对值进行dequeing并更新将itemid映射到totalcount的字典。
然后,工作线程每隔一分钟更新一次数据库,并显示结果。
附带问题: context.SaveChanges()
只保存对象中更改的内容吗? 或者它是否保存了对象的所有属性?
我觉得这个解决方案不是正确的,处理这样一个问题的最佳方法是什么?
您可以使用RepeatableRead
事务范围在读取和写入时锁定数据:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
...
context.SaveChanges();
scope.Complete();
}
实体框架跟踪实体字段更改并生成SQL代码以仅更新已修改的代码。 您可以明确指定只想更新一个实体属性并忽略其他更改:
context.Entry(entity).State = EntityState.Unchanged;
context.Entry(entity)
.Property(c => c.entityField).IsModified = true;
将对象附加到上下文中时它也很有用:
context.Attach(entity);
context.Entry(entity)
.Property(c => c.entityField).IsModified = true;
因为Attach
将实体及其属性放入Unchanged
状态的上下文中。
对于性能和并发问题,使用ExecuteSqlCommand更好:
string sql = "UPDATE Table SET LikeCount = LikeCount+1 WHERE Id={0}";
using (var context = new BloggingContext())
{
context.Database.ExecuteSqlCommand( sql, new SqlParameter("@Id", id));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.