第四节: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 ...
随机推荐
- i春秋——“百度杯”CTF比赛 十月场——EXEC(命令执行、带外通道传输数据)
查看源码得知由vim编写,所以查找备份以及交换文件 找到 /.index.php.swp ,下载后用vim -r恢复该文件即可得到源码 1 <html> 2 <head> 3 ...
- 实验吧——因缺思汀的绕过(sql with rollup)
题目地址:http://ctf5.shiyanbar.com/web/pcat/index.php 通读源码,得知出flag的条件 1.需要post提交uname以及pwd,否则直接die了 if ( ...
- Android 中发送邮件
第一步.导入第三方jar包 Android实现发送邮件,首先需要依赖additional.jar.mail.jar和activation.jar这3个jar包. Google提供了下载地址:https ...
- Spark GraphX图计算简单案例【代码实现,源码分析】
一.简介 参考:https://www.cnblogs.com/yszd/p/10186556.html 二.代码实现 package big.data.analyse.graphx import o ...
- JS引擎是如何工作的?从调用堆栈到Promise
摘要: 理解 JS 引擎运行原理. 作者:前端小智 原文:JS引擎:它们是如何工作的?从调用堆栈到Promise,需要知道的所有内容 Fundebug经授权转载,版权归原作者所有. 为了保证可读性,本 ...
- URL&HTTP协议
一般来讲,URL地址有五个部分组成,协议,域名,端口,路径,URL地址参数,通常“//'之前的部分就是协议 常用的协议有: http 超文本传输协议 htttps http+ssl ssh 用来实现远 ...
- vim编辑器-Linux从入门到精通第四天(非原创)
文章大纲 一.vi介绍二.vim三种模式(重点)三.命令模式四.模式间的切换(重点)五.末行模式六.编辑模式七.实用功能八.扩展九.学习资料下载十.参考文章 一.vi介绍 Vi编辑器是所有Unix ...
- 大数据技术原理与应用【第五讲】NoSQL数据库:5.3 NoSQL的四大类型
5.3 NoSQL的四大类型 5.3.1 键值数据库和列族数据库 可以分为四大类产品:键值数据库,列族数据库,文档数据库,图数据库 (代表) 1.键值数据库: 用的多:redis云数据库: ...
- 子网掩码的作用与IP网段的划分
公有IP地址分类 A类:1.0.0.0 到 127.255.255.255主要分配 给大量主机而局域网网络数量较少的大型网络 B类:128.0.0.0 到191.255.255.255 一般用于国际性 ...
- 通过async与await实现高效并发
withTimeoutOrNull: 在上一次https://www.cnblogs.com/webor2006/p/12010388.html中对于协程的超时机制进行了一个学习,上次用的是withT ...