EF中的高并发

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

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

1.使用步骤

1.添加RowVersion列

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

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

2.生成/升级EMD

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

做完这两步,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和数据库中不一致了,所以抛出异常)。

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

Entity Framework入门教程(13)---EF中的高并发的更多相关文章

  1. Entity Framework入门教程(3)---EF中的上下文简介

    1.DbContext(上下文类) 在DbFirst模式中,我们添加一个EDM(Entity Data Model)后会自动生成一个.edmx文件,这个文件中包含一个继承DbContext类的上下文实 ...

  2. Entity Framework入门教程(4)---EF中的实体关系

    这一节将总结EF是怎么管理实体之间的关系.EF与数据库一样支持三种关系类型:①一对一 ,②一对多,③多对多. 下边是一个SchoolDB数据库的实体数据模型,图中包含所有的实体和各个实体间的关系.通过 ...

  3. Entity Framework入门教程(5)---EF中的持久化场景

    EF中的持久性场景 使用EF实现实体持久化(保存)到数据库有两种情况:在线场景和离线场景. 1.在线场景 在线场景中,context是同一个上下文实例(从DbContext派生),检索和保存实体都通过 ...

  4. Entity Framework入门教程(19)---EF中使用事务

    EF中使用事务 这节介绍EF6中事务的使用.EF core中事务的使用方式和EF6中一模一样. 1.EF中的默认的事务 默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然 ...

  5. Entity Framework入门教程(7)--- EF中的查询方法

    这里主要介绍两种查询方法 Linq to entity(L2E)和Sql 1.L2E查询 L2E查询时可以使用linq query语法,或者lambda表达式,默认返回的类型是IQueryable,( ...

  6. Entity Framework入门教程(2)---EF工作流程

    EF工作流程 1.EF基本CRUD流程 下边的图就可以很清晰地展示EF的CRUD操作的基本工作流程: 这里做一个EF CRUD操作的简单总结:1.定义模型:这是EF工作的前提,定义模型包括定义领域类( ...

  7. Entity Framework入门教程(6)--- 在线场景中保存数据

    在线场景中保存数据 在线场景中保存实体数据是一项相当容易的任务,因为使用的是同一个context,这个context会自动跟踪所有实体发生的更改. 下图说明了在线场景中的CUD(创建,更新,删除)操作 ...

  8. Entity Framework入门教程(11)---EF6中的异步查询和异步保存

    EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法 ...

  9. Entity Framework入门教程(12)--- EF进行批量添加/删除

    EF6添加了批量添加/删除实体集合的方法,我们可以使用DbSet.AddRange()方法将实体集合添加到上下文,同时实体集合中的每一个实体的状态都标记为Added,在执行SaveChange()方法 ...

随机推荐

  1. python3打印当前时间和获取程序运行时间

    学习使用time模块和datetime模块. 通常我们想让程序等待几秒钟,再继续向下运行,time模块的sleep()方法是一个很好的选择.但是想通过time模块打印系统的当前时间,则比较麻烦.如下: ...

  2. 重置Visual Studio 2017的配置

    1,从命令行进入VS 2017安装目录下面的Common7\IDE文件夹. 例如,Windows 10系统中 VS 2017 企业版的默认安装目录如下: C:\Program Files (x86)\ ...

  3. #020PAT 没整明白的题L1-009 N个数求和 (20 分)

    后面的测试点过不去,两个错误一个超时. 目前未解决   L1-009 N个数求和 (20 分)   本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和 ...

  4. 初步了解.net

    一..net和C#是什么关系 .net是一个程序运行的平台,它是c#,vb,F#等程序运行的平台,为这些语言提供基础类库.公共语言运行时(CLR)等相关支持. C#是支持.net的一种编程语言..ne ...

  5. 【技术文章】《初识Python》

    本文地址:http://www.cnblogs.com/aiweixiao/p/8390413.html 原文地址 点击关注微信公众号 wenyuqinghuai 1.前言 早就知道Python这一语 ...

  6. 怎么在Vue的某个组件中根据组件tag标签名获取到对应的VueComponent实例呢

    1.以前玩omi框架的时候,有Omi.get方法来获取实例, ...好久没玩了,忘了.反正很喜欢该方法.2.如今想在vue里面怎么能够快速获取到对应组件标签名的的实例呢?3.文档也看过,似乎脑海中没啥 ...

  7. spring boot整合mybatis基于注解开发以及动态sql的使用

    让我们回忆一下上篇博客中mybatis是怎样发挥它的作用的,主要是三类文件,第一mapper接口,第二xml文件,第三全局配置文件(application.properties),而今天我们就是来简化 ...

  8. Elasticsearch 通关教程(二): 索引映射Mapping问题

    数据库建表的时候,我们的DDL语句一般都会指定每个字段的存储类型,例如:varchar,int,datetime等等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱. CREATE TABLE ...

  9. Activiti开发案例之activiti-app更换数据源

    前言 由于Activiti 默认使用的数据库是H2数据库,重启服务后相关数据会丢失.为了永久保存,所以要配置关系型数据库,这里我们选择 SqlServer ,有钱任性. 环境 Activiti6,Sq ...

  10. Lepus搭建企业级数据库全方位监控系统

    前言 Lepus(天兔)数据库企业监控系统是一套由专业DBA针对互联网企业开发的一款专业.强大的企业数据库监控管理系统,企业通过Lepus可以对数据库的实时健康和各种性能指标进行全方位的监控.目前已经 ...