ef 并发控制

ef 并发控制

ef 并发控制

什么是并发?
并发分悲观并发和乐观并发。
悲观并发:比如有两个用户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[]类型。
publicclass 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类型。
下面我们写一段代码来测试一下:
staticvoid 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 { publicint 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(社会保险号)标识为开放式并发,也写一个类似的代码测试一下:
staticvoid 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即可。
posted on 2018-08-10 22:45 micwin 阅读(...) 评论(...)  编辑 收藏

转载于:https://www.cnblogs.com/chinanetwind/articles/9457873.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Windows上设置BitLocker加密

BitLocker is a tool built into Windows that lets you encrypt an entire hard drive for enhanced security. Here’s how to set it up. BitLocker是Windows内置的工具&#xff0c;可用于加密整个硬盘驱动器以增强安全性。 设置方法如下。 When TrueCrypt controversially …

Java字节码方法表与属性表深度剖析

方法表&#xff1a; 在上一次咱们已经分析到了字段信息了&#xff0c;如下&#xff1a; 紧接着就是方法相关的信息了&#xff1a; 而它展开之后的结构为&#xff1a; 所以往后数2个字节&#xff0c;看一下方法的总数&#xff1a; 3个方法&#xff0c;可咱们只定义了两个方法呀&…

最大连续子数组和与JUnit测试

【题目】最大连续子数组和&#xff08;最大子段和&#xff09; 背景 问题&#xff1a; 给定n个整数&#xff08;可能为负数&#xff09;组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]a[i1]…a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0&#xff0c;依此定义…

笔记本电源适配器为什么总坏_为什么某些交流适配器和电源会发出啸叫声?

笔记本电源适配器为什么总坏Most of the time our AC adapters and power supplies tend to be quiet, but what does it mean when one makes a whining noise? Should you be concerned? Today’s SuperUser Q&A post has the answers to a worried reader’s question…

4412 字符类设备的设备号

一、静态申请字符类设备号 字符类设备函数在文件"include/linux/fs.h"中内核提供了三个函数来注册一组字符设备编号&#xff0c;这三个函数分别是 register_chrdev_region()alloc_chrdev_region()register_chrdev()register_chrdev_region()是提前知道设备的主次设备…

如何发现假库存照片(并将合适的人归于属性)

Spammers and other unscrupulous advertisers are always looking for new ways to get you click on their pages. One of the latest tactics is to steal popular and useful stock images—like the kind you sometimes see in news articles—and re-upload them elsewhe…

Mysql Hunter

一、简介自动化实施的过程中&#xff0c;我们通常都面临一个棘手的问题&#xff1a;数据的准备和恢复。即在成功执行一个自动化用例时&#xff0c;我们可能需要一定的数据前提&#xff0c;而为了使得整个前提不至于被其他的用例破坏&#xff0c;以至于我们有时不得不在自动化用…

如何在Windows 10上限制Wi​​ndows Update的下载带宽

Windows 10’s Fall Creators Update gives you more control of Windows Update’s downloads and uploads. You can now set a download bandwidth limit, ensuring Windows Update won’t hog your Internet connection with its background downloads. Windows 10的Fall Cr…

Elasticsearch嵌套查询

2019独角兽企业重金招聘Python工程师标准>>> 一、背景 最近在做基于宴会厅档期的商户搜索推荐时&#xff0c;如果用传统平铺式的mapping结构&#xff0c;无法满足需求场景&#xff0c;于是用到了Elasticsearch支持的Nested(嵌套)查询。 二、普通对象与嵌套对象的索引…

如何使用PowerShell提升开发效率(以Windows Embedded CE为例)

简介 本文讲述如何使用Powershell通过RAPI来控制Windows Embedded CE和Windows Mobile设备。 缘由 我入行的时候是做AS400 RPG和UNIX C开发的&#xff0c;所有开发环境都是字符界面&#xff0c;因此习惯了vigrepmake的开发模式。后来开始做Windows的开发&#xff0c;开始也不大…

Windows7旗舰版磁盘分区详解—附分区步骤截图

最近工作中配置使用联想的Thinkpad TL系列本本.当然原装的系统时刚发布的Windows RTM旗舰版.在考虑买之前也参考了戴尔 苹果的等等, 但个人私下也是一直在用Tinkpad系列, 相比其他的品牌本人还是比较钟情于Tinkpad 非常实用的键盘. 以及简洁的外观.买回来一看这个TL系列原装的系…

outlook存档邮件_如何在Outlook 2013中存档电子邮件

outlook存档邮件We’ve always been told that backing up our data is a good idea. Well, that same concept can extend to email as well. You may want to archive your email every so often, such as monthly, quarterly, or even yearly. 我们一直被告知备份数据是一个…

计算机组装和维护_如何构建自己的计算机,第二部分:组装在一起

计算机组装和维护So you’ve selected your parts, double- and triple-checked their compatibility, and waited for economy shipping to bring them all to your door. It’s time to get to the fun part: putting them all together. 因此&#xff0c;您已经选择了零件&a…

Autofac之自动装配

从容器中的可用服务中选择一个构造函数来创造对象&#xff0c;这个过程叫做自动装配。这个过程是通过反射实现的 默认 思考这么一个问题,如果注册类型中存在多个构造函数,那么Autofac会选择哪一个来创建类型的实例 答案是"尽可能最多参数" class ConstructorClass {p…

对Emlog 6.0 Beta的完整代码审计过程

Emlog 6.0 beta版本&#xff0c;这可能是最后一篇关于PHP语言CMS的代码审计文章&#xff0c;此次将详细记录完整的审计过程。 文章基本上完整记录小东的对此CMS审计过程&#xff0c;或许显得繁琐&#xff0c;但代码审计的过程就是这样&#xff0c;发现可能项&#xff0c;然后精…

SINOCES 2011

突然发现又好久没写过日志了 是在是太懒了… 难得休假去看了眼消费电子 感觉实在是一年不如一年 佳能、索尼不见踪影&#xff0c;相机满场没见一家&#xff08;大牌子是真没见到&#xff09; 华硕技嘉微星等主板厂商同样失踪… PC方面&#xff0c;联想貌似是来卖电脑包鼠标的&a…

esim卡与ms卡的区别_什么是eSIM,它与SIM卡有何不同?

esim卡与ms卡的区别With the launch of the Apple Watch 3, the term “eSIM” has been thrown around a lot. And now, Google’s Pixel 2 is the first phone to use this new technology, it’s time we take a closer look at what it is, what it does, and what this me…

机器学习实战之logistic回归分类

利用logistic回归进行分类的主要思想&#xff1a;根据现有数据对分类边界建立回归公式&#xff0c;并以此进行分类。 logistic优缺点&#xff1a; 优点&#xff1a;计算代价不高&#xff0c;易于理解和实现。缺点&#xff1a;容易欠拟合&#xff0c;分类精度可能不高。 .适用数…

HDU 6343.Problem L. Graph Theory Homework-数学 (2018 Multi-University Training Contest 4 1012)

6343.Problem L. Graph Theory Homework 官方题解: 一篇写的很好的博客: HDU 6343 - Problem L. Graph Theory Homework - [(伪装成图论题的)简单数学题] 代码: 1 //1012-6343-数学2 #include<iostream>3 #include<cstdio>4 #include<cstring>5 #include<…

Android GridView LruCache

照片墙这种功能现在应该算是挺常见了&#xff0c;在很多应用中你都可以经常看到照片墙的身影。它的设计思路其实也非常简单&#xff0c;用一个GridView控件当作“墙”&#xff0c;然后随着GridView的滚动将一张张照片贴在“墙”上&#xff0c;这些照片可以是手机本地中存储的&a…