我有一个 UI 线程,它使用户能够设置实体的某些属性。
我还有工作线程,它们会自动修改实体的属性,重要的是,用户无权访问。
每个线程都有不同的内容是否安全,DbContexts
并且只依赖于我的编程来始终避免修改相同的属性,然后尝试SaveChanges()
在以不同方式修改相同实体的上下文上进行操作?
或者有没有一种更安全的方法来做到这一点,即程序员有可能在某一天更改代码,以便从两个不同的上下文安全地修改相同的属性?还是后一种情况只是程序员必须小心/重构的一种情况?
我有一个 UI 线程,它使用户能够设置实体的某些属性。
我还有工作线程,它们会自动修改实体的属性,重要的是,用户无权访问。
每个线程都有不同的内容是否安全,DbContexts
并且只依赖于我的编程来始终避免修改相同的属性,然后尝试SaveChanges()
在以不同方式修改相同实体的上下文上进行操作?
或者有没有一种更安全的方法来做到这一点,即程序员有可能在某一天更改代码,以便从两个不同的上下文安全地修改相同的属性?还是后一种情况只是程序员必须小心/重构的一种情况?
解决多线程环境下并发问题的三种方式:
locks
为正在编辑的项目完成 - 没有其他人可以编辑已经被编辑的项目。这是一种很难实现的方法,而且从性能的角度来看,这种方法也很糟糕——所有的编辑线程都在等待一个编写者,只是在浪费系统资源。lock
一些操作,则使用这种方法,但不是全部。实体框架作者鼓励您在应用程序中使用乐观的方式。简单的用例是向模型添加RowVersion
或类似名称的属性,并DBUpdatedException
在UPDATE
.
您可以使用该Code-First
解决方案,如下所示:
[Timestamp]
public byte[] RowVersion { get; set; }
或Database-First
解决方案(使用数据库编辑器添加列):
之后,您的简单案例代码将如下所示:
using (var context = new SchoolDBEntities())
{
try
{
context.Entry(student1WithUser2).State = EntityState.Modified;
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
Console.WriteLine("Optimistic Concurrency exception occured");
}
}
据我了解,您必须检查数据源的一些属性,所以我建议您阅读一篇关于此类用例的精彩文章(它是关于 MVC 应用程序的,但我相信您可以管理主要主意)。
您还可以在 MSDN 上的 Entity Framework 中找到几篇关于并发性的文章:
DbPropertyValues
访问复杂属性如您所见,这种情况完全依赖于开发人员,您可以选择大量模式来自己解决并发问题。