什么是并发?

并发分悲观并发和乐观并发。

悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修改。

乐观并发:同上面的例子,A,B两个用户同时登录,如果A先进入修改紧跟着B也进入了。A修改文档的同时B也在修改。如果在A保存之后B再保存他的修改,此时系统检测到数据库中文档记录与B刚进入时不一致,B保存时会抛出异常,修改失败。

EF中如何控制并发?

Entity Framework不支持悲观并发,只支持乐观并发。

如果要对某一个表做并发处理,就在该表中加一条Timestamp类型的字段。注意,一张表中只能有一个Timestamp的字段。

Data Annotations中用Timestamp来标识设置并发控制字段,标识为Timestamp的字段必需为byte[]类型。

public class Person{public int PersonId { get; set; }public int SocialSecurityNumber { get; set; }public string FirstName { get; set; }public string LastName { get; set; }[Timestamp]public byte[] RowVersion { get; set; }}

Fluent API用IsRowVersion方法

modelBuilder.Entity<Person>().Property(p => p.RowVersion).IsRowVersion();

我们看到生成的数据库中,RowVersion是timestamp类型。

下面我们写一段代码来测试一下:

       static void Main(string[] args){var person = new Person{FirstName = "Rowan",LastName = "Miller",SocialSecurityNumber = 12345678};//新增一条记录,保存到数据库中using (var con = new BreakAwayContext()){con.People.Add(person);con.SaveChanges();}var firContext = new BreakAwayContext();//取第一条记录,并修改一个字段:这里是修改了FirstName//先不保存var p1 = firContext.People.FirstOrDefault();p1.FirstName = "Steven";//再创建一个Context,同样取第一条记录,修改LastName字段并保存using (var secContext = new BreakAwayContext()){var p2 = secContext.People.FirstOrDefault();p2.LastName = "Francis";secContext.SaveChanges();}try{firContext.SaveChanges();Console.WriteLine(" 保存成功");}catch (DbUpdateConcurrencyException ex){Console.WriteLine(ex.Entries.First().Entity.GetType().Name + " 保存失败");}Console.Read();}

上面我们实例化了三个DbContext,第一个增加一条记录到数据库中,第二个修改刚增加的记录但不保存,然后第三个Context也取刚新增的记录并保存,最后再保存第二个Context,结果保存失败。

可以看到我们的并发控制取到了作用。

分析EF生成的SQL语句:

exec sp_executesql N'update [dbo].[People]
set [LastName] = @0
where (([PersonId] = @1) and ([RowVersion] = @2))
select [RowVersion]
from [dbo].[People]
where @@ROWCOUNT > 0 and [PersonId] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8)',@0=N'Francis',@1=1,@2=0x00000000000007D1

可以看到,它在取对应记录的时候把RowVersion也作为筛选条件。上面例子中的secContext保存的时候,数据库中的RowVersion字段的值就变了,所以firContext保存的时候用原来的RowVersion取值,自然就取不到相应的记录而报错。

如果我们只是要对某个字段作并发控制呢?别着急,EF也有办法。

Data Annotations中用ConcurrencyCheck来标识

 public class Person{public int PersonId { get; set; }[ConcurrencyCheck]public int SocialSecurityNumber { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public byte[] RowVersion { get; set; }}

Fluent API用IsConcurrencyToken方法

modelBuilder.Entity<Person>().Property(p => p.SocialSecurityNumber).IsConcurrencyToken();

上面的实体中,我们将SocialSecurityNumber(社会保险号)标识为开放式并发,也写一个类似的代码测试一下:

 static void Main(string[] args){var person = new Person{FirstName = "Rowan",LastName = "Miller",SocialSecurityNumber = 12345678};//新增一条记录,保存到数据库中using (var con = new BreakAwayContext()){con.People.Add(person);con.SaveChanges();}var firContext = new BreakAwayContext();//取第一条记录,并修改SocialSecurityNumber字段//先不保存var p1 = firContext.People.FirstOrDefault();p1.SocialSecurityNumber = 123;//再创建一个Context,同样取第一条记录,//修改SocialSecurityNumber字段并保存using (var secContext = new BreakAwayContext()){var p2 = secContext.People.FirstOrDefault();p2.SocialSecurityNumber = 456;secContext.SaveChanges();}try{firContext.SaveChanges();Console.WriteLine(" 保存成功");}catch (DbUpdateConcurrencyException ex){Console.WriteLine(ex.Entries.First().Entity.GetType().Name + " 保存失败");}Console.Read();}

运行结果同样是保存失败,说明我们的并发控制起作用了。

分析一下EF执行的SQL:

exec sp_executesql N'update [dbo].[People]
set [SocialSecurityNumber] = @0
where (([PersonId] = @1) and ([SocialSecurityNumber] = @2))
',N'@0 int,@1 int,@2 int',@0=123,@1=1,@2=12345678

可以看到,EF将我们要并发控制的列SocialSecurityNumber也作为一个筛选条件,这样firContext保存的时候也会因为的数据库中SocialSecurityNumber值变了,取不到对应的记录而更新失败。

补充一下:如果是EDMX如何将字段设置为Concurrency。很简单,在对应的字段上右键-属性。在打开的属性窗口中有一个并发模式,你将它选择为Fixed即可。

如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)

Entity Framework 并发处理相关推荐

  1. C#综合揭秘——Entity Framework 并发处理详解

    引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...

  2. Entity Framework 基础

    一.什么是Entity Framework 微软官方提供的ORM工具,ORM让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上.EF提供变更跟踪.唯一性约束.惰性加载.查询事物等.开 ...

  3. C#:实体框架EF(entity framework)

    本文来自:http://www.cnblogs.com/xuf22/articles/5513283.html 一.什么是Entity Framework 微软官方提供的ORM工具,ORM让开发人员节 ...

  4. 浅析Entity Framework Core中的并发处理

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core的并发处理方式. 1.常见的并发处 ...

  5. 在Entity Framework中使用存储过程(一):实现存储过程的自动映射

    之前给自己放了一个比较长的假期,在这期间基本上没怎么来园子逛.很多朋友的留言也没有一一回复,在这里先向大家道个歉.最近一段时间的工作任务是如何将ADO.NET Entity Framework 4.0 ...

  6. EF-Entity Framework 相关技术点收集贴

    不定期.偶尔.添加更新 在网络上看到或者自己开发过程中碰到的EF-Entity Framework相关技术点 本文地址:http://www.cnblogs.com/vnii/archive/2012 ...

  7. 《你必须掌握的Entity Framework 6.x与Core 2.0》正式出版感想

    前言 借书正式出版之际,完整回顾下从写博客到写书整个历程,也算是对自己近三年在技术上的一个总结,整个历程可通过三个万万没想到来概括,请耐心阅读. 写博.写书完整历程回顾 从2013年12月注册博客园账 ...

  8. Entity Framework Code First在Oracle下的伪实现

    为什么要说是伪实现,因为还做不到类似MsSql中那样完全的功能.Oralce中的数据库还是要我们自己手动去创建的.这里,我们舍掉了Model First中的EDMX文件,自己在代码里面写模型与映射关系 ...

  9. Entity Framework:Code-First Tutorial开篇

    这个系列文章是关于Entity Framework Code-First的英文系列文章,内容不错,每篇一个主题知识点介绍,特转载过来 原文地址:http://www.entityframeworktu ...

最新文章

  1. 【算法】BFS刷题总结
  2. python bound unbound method
  3. golang 字符串 去首尾字符
  4. beautifulsoup4
  5. Apache 重写规则的常见应用 (rewrite)
  6. Java虚拟机组成详解
  7. java(线程池的创建方式,和线程池的原理)
  8. Linux+QT界面开发(含数据库)小结
  9. 利用ffmpeg提供的库(API)进行音频与视频的编码并生成文件
  10. 京东公布3.8“她的节”消费数据:奢品服饰成交额同比增长170%
  11. spark阶段和任务小结
  12. JAVA类加载的委托模型
  13. Linux 入门记录:五、vi、vim 编辑器
  14. python给每个key添加数据_一文看懂Python collections模块的高效数据类型
  15. xmind模板打包下载
  16. 汽车使用总结(七)--侧方停车
  17. linux177端口怎么打开,AIX5.3,如何使用xmanager管理?177端口打不开的相关推荐_ChinaUnix论坛...
  18. Road to Coder _Game
  19. android 开源fc模拟器_准备开发一款开源NES模拟器
  20. 由于这台计算机没有远程桌面客户端

热门文章

  1. Linux引出环境变量的关键字,学习记录008-linux常用命令/设置系统and用户环境变量two(示例代码)...
  2. python实战经典例子_Python入门经典实例
  3. python识别复杂验证码2020_Python识别验证码!学会这步,百分之60的网站你基本都能识别了!...
  4. 20200308: 生成每种字符都是奇数个的字符串灯泡开关 III(leetcode5352-5353)
  5. java 同步块_java 同步块(Java Synchronized Blocks)
  6. 乌班图 修改ip_Ubuntu临时和永久修改ip地址掩码和网关
  7. div添加一个点击事件(绑定点击事件)
  8. redis服务端的maxclient和最大连接空闲时间设置
  9. 内部控制中对权限分配的要求、权限分配的实现方法
  10. VB 子类化技术详解