Entity Framework入门教程(13)---EF中的高并发

EF中的高并发

  这里只介绍EF6中database-first开发方案的高并发解决方案,code-first开发方案中的高并发会在之后的EF CodeFirst系列中介绍。html

  EF默认支持乐观并发:咱们从数据库加载了一条数据,这是有人修改了这条数据,而咱们手中用的仍是旧数据,这就出现了脏读,这个时候咱们修改了这条数据而后执行SaveChange()会发生什么呢?EF在保存数据时会首先查看数据库中的数据有没有改变过,数据没有改变就执行保存;数据改变了会抛出异常,咱们再次提交前必须解决冲突(提到解决冲突是否是想到了git提交中的冲突?EF中解决高并发的方法和git提交的方法采用的思想是同样的,往下看就知道了)。git

1.使用步骤

1.添加RowVersion列数据库

  在EF中database-first开发模式中,为了解决高并发问题咱们能够为数据表填加一个timestamp类型的的列,列名为rowversion,rowversion是一个二进制的数据,在每次的添加/修改操做后rowversion的值都会变大并发

以Student实体为例,给Student表添加一个Rowversion列,类型为timestamp,以下所示:高并发

2.生成/升级EMDpost

若是没有EDM经过数据库生成新的实体数据模型,若是有EDM则右击设计器->Update Model From Database ->Refresh Student table,这时咱们就能够在设计器中看到RowVersion属性了,RowVersion属性的Concurrency Mode设置为Fixed,以下图spa

作完这两步,EF API在执行Update时,会把RowVersion添加到where子句中(就像这样:update tb set cloName=xxx where Id=@id and RowVersion=@rowversion),若是where子句中的RowVersion值和数据库中的不同就抛出DbUpdateConcurrencyException设计

2.一个栗子

Student student = null; 

using (var context = new SchoolDBEntities())
{
    student = context.Students.First();
}

//修改学生名字
Console.Write("Enter New Student Name:");
student.StudentName = Console.ReadLine(); //Assigns student name from console

using (var context = new SchoolDBEntities())
{
    try
    {
        context.Entry(student).State = EntityState.Modified;
        context.SaveChanges();

        Console.WriteLine("修改为功!");
    }
    catch (DbUpdateConcurrencyException ex)
    {
        Console.WriteLine("发生高并发异常!");
    }
}

假设有两个用户都在执行上边的代码,User1和User2拿到了同一个Student实例,User1打字快1秒就把这个Student的用户修改了,并在数据库保存成功(User1执行Update时RowVersion和数据库一致,因此不报错,保存完成后Student的RowVersion自动改变了),这时User2也完成了修改,在User2执行保存到数据库时(生成的Update语句中的RowVersion和数据库中不一致了,因此抛出异常)。code

 

EF系列目录连接:Entity Franmework系列教程汇总htm