第四节:EF Core的并发处理
1.说明
和EF版本的并发处理方案一致,需要知道乐观并发和悲观并发的区别,EF Core只支持乐观并发;监控并发的两种方案:监测单个字段和监测整条数据,DataAnnotations 和 FluentApi的两种配置方式。
(PS:EF Core中的并发处理模式和EF中的基本类似,其他相关概念参考:第二十节: 深入理解并发机制以及解决方案(锁机制、EF自有机制、队列模式等):)
2. 两个概念
(1).悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了, 只有等A修改完,完全退出的时候B才能进入修改。
(2).乐观并发:A,B两个用户同时登录,如果A先进入修改紧跟着B也进入了。A修改文档的同时B也在修改,如果在A保存之后/ B再保存他的修改,此时系统检测到数据库中文档记录与B刚进入时不一致,B保存时会抛出异常,修改失败。
3. 监测单个字段
用到的表结构:

(1). 监测那个字段就配置哪个字段,有两种配置方式,如下:
A. DataAnnotations配置:在对应字段上加特性 [ConcurrencyCheck]
B. FluentApi配置: entity.Property(p => p.age).IsConcurrencyToken();
提交数据库的时候,发现该字段中的值已经被篡改了,就会进入DbUpdateConcurrencyException并发异常中,这里面可以获取三个值:数据库原始值、 数据库现在值、内存中当前值。
通常的处理方式:
①. Reload一下,放弃当前内存中的实体,重新到数据库中加载当前实体,然后用当前数据库中的值进行相应的业务处理。
②. 直接提示用户,信息被修改,请重新操作一遍(可以更友好的提示一下)
(2).案例:
保证T_Concurrency01有一条id=01的记录(age=10),分别用上面的两种方式进行配置,测试的结果最终age=4,执行正确。
{
//保证T_Concurrency01有一条id=01的记录(age=10)
ypfContext db1 = new ypfContext();
ypfContext db2 = new ypfContext();
try
{
var data1 = db1.T_Concurrency01.Where(u => u.id == "").FirstOrDefault();
var data2 = db2.T_Concurrency01.Where(u => u.id == "").FirstOrDefault();
data1.age = data1.age - ;
int result1 = db1.SaveChanges();
data2.age = data2.age - ;
int result2 = db2.SaveChanges(); //发现age的值和原先查出来的不一致,会抛异常进入cache
}
catch (DbUpdateConcurrencyException ex)
{
var entityEntry = ex.Entries.Single();
var original = entityEntry.OriginalValues.ToObject() as T_Concurrency01; //数据库原始值 10
var database = entityEntry.GetDatabaseValues().ToObject() as T_Concurrency01; //数据库现在值 8
var current = entityEntry.CurrentValues.ToObject() as T_Concurrency01; //当前内存值 6
entityEntry.Reload(); //放弃当前内存中的实体,重新到数据库中加载当前实体
current.age = database.age - ; //应该拿着当前数据库实际的值去处理,即8-4=4
entityEntry.CurrentValues.SetValues(current);
int result3 = db2.SaveChanges();
}
}
4. 监测整条数据
用到的表结构:

(1). 首先要给该表在数据库中加一个字段(任意命名即可),通常叫“timeStamp”或“rowVersion”,然后进行配置:
A. DataAnnotations配置:在对应字段上加特性[Timestamp]
B. FluentApi配置: entity.Property(e => e.rowVersion).IsRowVersion();
提交数据库的时候,发现该表中任意字段中的值被篡改了,就会进入DbUpdateConcurrencyException并发异常中,这里面可以获取三个值:数据库原始值、 数据库现在值、内存中当前值。
通常的处理方式:
①. Reload一下,放弃当前内存中的实体,重新到数据库中加载当前实体,然后用当前数据库中的值进行相应的业务处理。
②. 直接提示用户,信息被修改,请重新操作一遍(可以更友好的提示一下)
(2). 案例
保证T_Concurrency02有一条id=01的记录(age=10),没别用上面的两种方式进行配置,还是用age来进行测试,测试的结果最终age=4,执行正确。
{
//保证T_Concurrency02有一条id=01的记录(age=10)
ypfContext db1 = new ypfContext();
ypfContext db2 = new ypfContext();
try
{
var data1 = db1.T_Concurrency02.Where(u => u.id == "").FirstOrDefault();
var data2 = db2.T_Concurrency02.Where(u => u.id == "").FirstOrDefault();
data1.age = data1.age - ;
int result1 = db1.SaveChanges();
data2.age = data2.age - ;
int result2 = db2.SaveChanges(); //发现age的值和原先查出来的不一致,会抛异常进入cache
}
catch (DbUpdateConcurrencyException ex)
{
var entityEntry = ex.Entries.Single();
var original = entityEntry.OriginalValues.ToObject() as T_Concurrency02; //数据库原始值 10
var database = entityEntry.GetDatabaseValues().ToObject() as T_Concurrency02; //数据库现在值 8
var current = entityEntry.CurrentValues.ToObject() as T_Concurrency02; //当前内存值 6
entityEntry.Reload(); //放弃当前内存中的实体,重新到数据库中加载当前实体
current.age = database.age - ; //应该拿着当前数据库实际的值去处理,即8-4=4
entityEntry.CurrentValues.SetValues(current);
int result3 = db2.SaveChanges();
}
}
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
第四节:EF Core的并发处理的更多相关文章
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- .Net Core+Angular6 学习 第四部分(EF Core(Code First))
目的: 打算通过EF core 练习从database receive data 显示到UI. 1. 创建一个新的project Model.定义一个 base interface entity以及实 ...
- 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法
一. 背景 上一个章节,介绍了EF调用两类SQL语句,主要是借助 ExecuteSqlCommand 和 SqlQuery 两个方法来完成,在本章节主要是复习几类存储过程的写法和对应的EF调用这几类 ...
- 第十四节: EF的三种模式(四) 之 原生正宗的 CodeFirst模式的默认约定
一. 简介 1. 正宗的CodeFirst模式是不含有edmx模型,需要手动创建实体.创建EF上下文,然后生成通过代码来自动映射生成数据库. 2. 旨在:忘记SQL.忘记数据库. 3. 三类配置:On ...
- Entity Framework (EF) Core工具创建一对多和多对多的关系
一. EntirtyFramework(EF)简介 EntirtyFramework框架是一个轻量级的可扩展版本的流行实体框架数据访问技术,微软官方提供的ORM工具让开发人员节省数据库访问的代码时间 ...
- 第五节:EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope)
一. 说明 EF版本的事务介绍详见: 第七节: EF的三种事务的应用场景和各自注意的问题(SaveChanges.DBContextTransaction.TransactionScope). 本节主 ...
- 第一节:EF Core简介和CodeFirst和DBFirst两种映射模式(以SQLite和SQLServer为例)
一. EF简介 1. 定义 Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台的数据访问技术,它还是一种对象关系映射器(ORM),它使.NET 开发人员能够使用面向对 ...
- EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
前言 终于踏出第一步探索EF Core原理和本质,过程虽然比较漫长且枯燥乏味还得反复论证,其中滋味自知,EF Core的强大想必不用我再过多废话,有时候我们是否思考过背后到底做了些什么,到底怎么实现的 ...
- [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
随机推荐
- 响应式开发 纯CSS实现隐藏菜单栏
// 将要隐藏的菜单设置 display: block; // 然后在菜单上面设置一个点击选项,如“菜单”<label for="toggle-checkbox" id=&q ...
- SpringBoot自定义Condition注解
最近碰到个这样的需求,需要同一套代码适配个版本数据库(数据库不同,且部分表的字段及关联关系可能会不同),即这套代码配置不同的数据库都能跑.项目采用的框架为SpringBoot+Mybatis. ...
- Kubernetes概念之deployment
一整天一整天的坐在办公室,真的很~~~,懵圈中....,求解救. 本文通过<Kubernetes权威指南>的概念部分学习总结 Deployment作用 Deployment与RC的作用其实 ...
- 基于Spring Boot的注解驱动式公众号极速开发框架FastBootWeixin
本框架基于Spring Boot实现,使用注解完成快速开发,可以快速的完成一个微信公众号,重新定义公众号开发. 在使用本框架前建议对微信公众号开发文档有所了解,不过在不了解公众号文档的情况下使用本框架 ...
- mapping 映射
es的映射就相当于编程语言中给变量定义类型,定义后的变量使用起来更高效,未定义的变量相较于定义的性能肯定是不如的.所以需要掌握es映射. 未定义映射es会对提供的数据进行类型猜测,如果对自动判断的类型 ...
- Eric6安装问题解决
按照http://eric-ide.python-projects.org/eric-download.html中的说明,执行命令:python install.py 却遇到下面的问题: Compil ...
- SRT字幕格式
[时间:2019-03] [状态:Open] [关键词:字幕,SRT,文件格式] 0 引言 视频文件中最简单.最常见的外挂字幕格式是SRT(SubRip Text).本人找了好久也没找到类似的标准文档 ...
- linux突然不能上网,eth0网卡消失
情况:之前可以正常浏览网页,没有动其它的地方,浏览器突然不能上网 ifconfig # 发现eth0网卡不见了,只有lo卡 ifconfig -a # 发现了eth0,但是没有IP地址 dhclien ...
- 朱石景 201671010457 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 http://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...
- Nginx——端口负载均衡
前言 Nginx做的代理后面SpringBoot的项目,1N3T的架构,Tomcat的配置也进行了相应的调优. 配置 这里主要来简单的说下Nginx的端口负载均衡,具体的大家可以参考 Nginx文档 ...