Entity Framework 乐观并发控制
一、背景
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
二、悲观并发和乐观并发
悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修改。
乐观并发:同上面的例子,A,B两个用户同时登录,如果A先进入修改紧跟着B也进入了。A修改文档的同时B也在修改。如果在A保存之后B再保存他的修改,此时系统检测到数据库中文档记录与B刚进入时不一致,B保存时会抛出异常,修改失败。
乐观并发的基本出发点是:当保存数据的时候抱着一种乐观的态度,不期望发生并发冲突,即使万一发生并发冲突,也能捕捉到冲突异常,然后根据策略解决冲突,而解决冲突的方式一般分为Client wins(以后操作者为赢) 和 Store wins(以先存储的数据为赢)。
三、EF中如何控制并发

Resolving optimistic concurrency exceptions with Reload
使用Reload数据作为解决乐观并发异常的策略之一,我在这里就讲数据Reload这一种策略就好了,除了Reload外,还有其他几种冲突解决策略,详见参考文献中EF官方团队博客。
using (var context = new UnicornsContext())
{
bool saveFailed;
do
{
saveFailed = false;
var unicorn = context.Unicorns.Find();
unicorn.Name = "tom";
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
saveFailed = true;
// Update the values of the entity that failed to save
// from the store
ex.Entries.Single().Reload();
}
} while (saveFailed);
}
四、SqlProfiler看原理
完成以上步骤后,您的程序就具备了乐观并发处理的能力了,但是,其中的原理是什么呢?从SqlProfiler监控结果来看,EF是将并发模式设置为Fixed的字段放在where子句里,后操作会因为取不到相应的记录而更新失败,打个比方说,当两个用户同时对同一条记录(ID=1,Count=10)进行读、写操作的时候,A、B同时读取记录的时候,Count都等于10,A用户先进行Update减1操作,此时(ID=1,Count=9),而此时B用户稍微晚一点点再进行Update操作的时候,因为Count已经被A修改成9了,已经不存在(ID=1,Count=10)的记录了,所以B最终执行影响行数为0,EntityFramework抛出并发异常:
如:我们给Count属性的并发模式设置成Fixed的话,那生成的SQL语句如下:
exec sp_executesql N'update [dbo].[OrderLog]
set [Count] = @
where (([ID] = @) and ([Count] = @2))',N'@ int,@ int,@ int',@0=78,@1=1,@2=9
当EntityFramework执行更新操如果影响行数为0,就会抛出异常,相关源代码如下所示:

五、总结
个人认为,乐观并发控制适用于并发量还不是很大情况,也就是符合乐观并发的初衷,当保存数据的时候不期望发生并发冲突,一旦发生冲突,也能捕捉到冲突异常,然后根据策略解决冲突或者提示用户操作失败等,但是,当并发量很大的时候,我认为乐观并发就显得并不那么适用了,个人建议,做评估项目并发风险和做并发冲突的测试,假如完全可以接受,大可以应用EntityFramework的乐观并发控制,实现起来也比较简单,假如项目并发量确实很大,那可以考虑别的技术方案实现,比如消息队列……等。
参考文献
(1)微软EntityFramework团队博客: Using DbContext in EF 4.1 Part 9: Optimistic Concurrency Patterns
(2)Gyoung: Entity Framework 并发处理
Entity Framework 乐观并发控制的更多相关文章
- Entity Framework 乐观并发处理
Entity Framework 乐观并发处理 有一段时间没有更新博客了,今天终于有一些时间,和大家讨论一个Entity Framework 乐观并发处理的问题.首先需要说明的是,这里提到的 “并发” ...
- C# Entity Framework并发处理
原网站:C# Entity Framework并发处理 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NE ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
- [转]C#综合揭秘——Entity Framework 并发处理详解
本文转自:http://www.cnblogs.com/leslies2/archive/2012/07/30/2608784.html 引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的 ...
- Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...
- Entity Framework Code First实现乐观并发
Entity Framework Code First实现乐观并发 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: h ...
- Entity Framework 6 Code First 系列:无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制
无需修改实体和配置,在MySql中使用和SqlServer一致的并发控制.修改RowVersion类型不可取,修改为Timestamp更不可行.Sql Server的RowVersion生成一串唯一的 ...
- Programming Entity Framework 翻译(1)-目录
1. Introducing the ADO.NET Entity Framework ado.net entity framework 介绍 1 The Entity Relationship Mo ...
- Entity Framework 并发处理
什么是并发? 并发分悲观并发和乐观并发. 悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修 ...
随机推荐
- Queue、进程、线程、协程
参考博客地址 http://www.cnblogs.com/alex3714/articles/5230609.html 1.python GIL全局解释器锁 python调用的操作系统的原生线程,当 ...
- information_schema系列二(列,列权限,事件,存储引擎)
这个系列的文章主要是为了能够让自己了解MySQL5.7的一些系统表,统一做一下备注和使用,也希望分享出来让大家能够有一点点的受益. 1:COLUMNS 老规矩.查一下这个表,看一下记录,由于这个是看表 ...
- codeforces 361 E - Mike and Geometry Problem
原题: Description Mike wants to prepare for IMO but he doesn't know geometry, so his teacher gave him ...
- UVa 10055 - Hashmat the Brave Warrior
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...
- android开源框架android-async-http使用
原文地址:http://www.open-open.com/lib/view/open1369637365753.html android-async-http开源框架可以是我们轻松的获取网络数据或者 ...
- VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的
消息作用: 在进程间共享数据(内部通过创建内存映射文件) 消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT { ULONG_PTR dw ...
- 【软件工程】电梯调度的初步实现 李亚文&&郭莉莉
一.开门见山,代码粘 using System; using System.Collections.Generic; using System.Data; using System.Drawing; ...
- windows下安装多个tomcat服务
摘要 公司服务器已经部署2个tomcat,分别属于不同的系统.今天新开发的系统也要上线测试,故新增一个tomcat服务器. 1.官网下载tomcat 7 解压缩版本.我使用的是 apache-tomc ...
- JQuery 简单的文字超出部分隐藏下拉显示
HTML代码: <body> <div class="txt_bos"><!--在每一个放置文字的class外面包一个div,以便设置动画样式用,同样 ...
- pause 和 title
-------siwuxie095 pause 暂停批处理程序,并显示:请按任意键继续- 暂停高级技巧: pause>nul 只暂停,不显示任何信息,且光标移到下一行 如果不想用默认提示语:请按 ...