知识大全 ADO.NET Entity Framework 试水——并发

Posted 冲突

篇首语:生活只有在平淡无味的人看来才是空虚而平淡无味的。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 ADO.NET Entity Framework 试水——并发相关的知识,希望对你有一定的参考价值。

ADO.NET Entity Framework 试水——并发  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  提到数据库操作 特别是企业级的数据库应用 就不得不提一个多人操作时经常会产生的问题——并发冲突 本文首先来看一下什么是并发冲突 传统的并发冲突有现有的处理方式 最后 结合EF 看一个处理并发冲突的实例      一 要完成本文中的实例 您需要作如下准备      将Visual Studio 及 NET Framework 升级到SP 点击转到升级地址   安装SQL SERVER VS 中自带的EXPRESS版的SQL SERVER应该也可以用   下载并附加数据库 点击下载DemoDbV   创建一个VB Console Application 并且取一个合适的名字(例如 Concurrency之类的) 注意 目标Framework要设置成 版         二 什么是并发冲突      让我们来看一个跟取款相关的例子 某年某月某日某时某分 老王在A取款机取钱 他儿子小王同时在B取款机取钱(不要问我为什么这么巧^_^) 他俩从同一个账号上取 于是就发生了如下一序列的操作      A取款机向中央数据库提问 这账上还有多少钱?      B取款机向中央数据库询问 这账上还有多少钱?      中央数据库回答A取款机 W      中央数据库回答B取款机 W      然后 老王对A取款机说 我要取出 W      同时 小王对B取款机说 我要取出 W      A取款机就算了一下 W W= W> 于是就吐出 W现金给了老王 并且准备告诉中央数据库 现在还剩 W啦 但是 就在它告诉中央数据库之前 发生了以下的事情      B取款机计算了一下 W(此时 它还不知道余额已经成 W了 因为A取款机还没有告诉中央数据库)减去 W等于 W大于 于是就吐出 W现金给了小王 然后 它当然也要知会中央数据库      中央数据库于是收到A取款机的消息 说 这个账号还剩 W 于是刷新余额为 W 然后又收到B取款机说还剩 W 于是 就刷新余额为 W      呵呵 于是 小王+老王的账户里一共存有 W元 结果老王取了 W元 小王取了 W元 账户里却还剩了 W元!~@#$%^&      这就是一种并发冲突 由于同一时间有两个或者多个端在对同一数据进行操作 从而导致数据发生了错误 如果取款机真的以这样的方式来处理并发 那么 我现在就不写这片文章了——赶紧发动全家对表 说好了在某一时刻同时取钱去^_^

  三 常见的并发冲突处理方式      一般来说 我们把并发冲突处理方式归结为 类      第一类 放任不管方式 第二类 开放式并发处理方式 第三类 保守式并发处理方式             放任不管方式      与其说这是一种处理并发冲突的方式 不如说 它是一种没有对并发冲突做任何处理的方式 但是在许多过去的系统里 由于没有考虑到多用户 网络应用等情况 这种 处理方式 还真存在于不少系统中      举例来说 A B两人从数据库中获取了同一个笔记本的信息 例如 IBM ThinkPad T 吧 然后 A把牌子改成了 Lenovo ThinkPad B把型号改成了T A 然后 他们开始提交了 此时 如果A先提交 然后B提交 那么 最后的结果是 IBM ThinkPad T A 反之 则变成Lenovo ThinkPad T      总之一句话 谁最后提交谁老大 想像一下 如果A修改了 个属性的值 B修改了 个属性的值 那么 对于先提交的A来说 这将是一个多么惨痛的打击: )      虽然这种放任不管的方式似乎不太负责任 但是 其处理性能却是相对较高的             开放式并发处理      开放式并发处理 老外叫做Optimistic Concurrency——乐观的并发 这种并发处理方式要求我们对并发抱有一种乐观的态度 百分之九十九点九九不会发生并发冲突 万一发生了 系统也能捕获到冲突 或者根据策略自动处理 或者 就提醒一下用户 让用户来决定是不是要继续提交      仍然用上面的例子来说这事儿 A B两个人同时获取了笔记本的信息 IBM ThinkPad T 然后……(此处跟上例做一样的修改 直到提交)此时 如果A先提交 那么 B提交的时候 系统会发现 哎哟 不好 有并发冲突了 就会抛个异常给B 让B知道 发生并发冲突了 然后 B就可以根据实际情况 选择相应的处理策略(比如 继续提交进行覆蓋或者取消提交等等) 相反 如果B先提交 那么 A提交时 就会得到相应的提醒      这样的并发处理方式 可以说在可靠性与性能上取得平衡 适合于对数据可靠性要求不是特别严格 需要较高的性能 并且不会大量发生并发的场合             保守式并发处理      这是最为严谨的一种并发冲突的处理方式 它把并发转化为了串行操作      例如 A从数据库中获取了笔记本信息 IBM ThinkPad T B也要对其进行修改 但此时由于A已经从数据库中将数据取出 因此 B被置于等待状态 直到A把数据修改完提交了 数据库数据更新为Lenovo ThinkPad T 了 此时 数据库才把数据给B 那么B就可以在Lenovo ThinkPad T 的基础上 把它修改为Lenovo ThinkPad T A 而在B提交前 其它一切针对此记录的操作都得排除等著B      这样子当然非常理想 由于不存在并发 自然也就消除了并发冲突的问题 但是 这种锁也存在着较为隐蔽的风险 如果A修改了数据 一直不提交 或者A因为故障 没有办法提交 那么 其它所有的相关的操作 都将被阻碍住 因此 只有对数据准确性要求极高并且用户可以忍受等待的情况下 使用这种并发冲突的处理方法      四 EF并发冲突处理实例      EF发布时 提供了两种并发冲突处理方式 放任不管方式和开放式并发 默认采用放任不管的方式处理      如果要使用开放式并发 那么 必须设置相应属性上的Concurrency Mode值为Fixed 我们先对实体类的属性进行修改 让其支持开放式并发 然后来模拟一个并发的序列 看看怎么来处理并发冲突      当前数据库情况如图 所示               第一步 在概念模型设计器里 按照图 所示 分别把Notebook Brand和Notebook Type属性的Concurrency Mode设置为Fixed      然后 我们写一段代码来模拟一个并发冲突的情况       Create object context      Dim objContext As New NbWhEntities()      Dim objContext As New NbWhEntities()             Query the same record as entities      Dim laptop = (From aLaptop In objContext Notebook _       Where aLaptop Id = _       Select aLaptop) FirstOrDefault()            Dim laptop = (From aLaptop In objContext Notebook _       Where aLaptop Id = _       Select aLaptop) FirstOrDefault()             Modify the entity      laptop Brand = Lenovo ThinkPad      laptop Type = laptop Type & A             Submit st object context      objContext SaveChanges()            Try       Submit nd object context and cause cuncurrency exception       objContext SaveChanges()      Catch ex As OptimisticConcurrencyException       Using refresh method to       objContext Refresh(Objects RefreshMode StoreWins laptop )       We should load the new data from db and ask user to change it again       objContext SaveChanges()      End Try         我们创建了两个Object Context 分别查询出了同一个实体 第一个修改其品牌为 Lenovo ThinkPad 第二个同时将其型号修改为 T A 然后 第一个实体保存 然后 第二个保存 由于我们在Brand属性上设置了Concurrency Mode为Fixed 而此时 laptop 中的Brand属性的值应该是一开始取得的T 而数据库里的值是 Lenovo T 于是 系统就会抛出 OptimisticConcurrencyException (开放式并发异常) 当程序捕获到异常以后 就可以使用Object Context的Refresh方法对异常采取处理 由于没有在刷新laptop 以后 未对其作任何修改 故最终结果将与laptop 提交时的结果一致      这里 Refresh的第一个参数值得注意一下 它是一个枚举值 有两个选项 StoreWins或者是ClientWins 见名知义 如果是StoreWins 那么 Refresh以后 laptop 的值将与数据库里的对应记录的值一致(修改会丢失) 而如果ClientWins 则laptop 的值保持 并且提交以后 会把objContext 提交的修改覆蓋      其实 这两种方法均不完美 总会导致一部分修改丢失 但是 这总比在不知情的情况下的覆蓋要好      另外 需要说明 上面的方法 只是对并发冲突的一种模拟 这样的模式 在处理并发冲突时会有问题 一般的处理方法是 当检测到并发冲突时 提示用户会重新从数据库载入数据 然后 让用户在新数据的情况下重新修改后再次提交 直到不再有并发冲突发生      这样 看似可能成为一个无穷尽的痛苦的过程 但实际上 由于这种处理方式是基于对并发冲突的乐观估计来设计的 因此 当我们认为并发冲突很少有可能发生时 这种处理方式可以有效避免数据被无意识的覆蓋问题            五 示例代码下载      点击下载    cha138/Article/program/net/201311/11293

相关参考

知识大全 ADO.NET Entity Framework 试水——并发[4]

ADO.NETEntityFramework试水——并发[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 ADO.NET Entity Framework 试水——并发[3]

ADO.NETEntityFramework试水——并发[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 ADO.NET Entity Framework 试水——并发[1]

ADO.NETEntityFramework试水——并发[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 ADO.NET Entity Framework 试水——并发[2]

ADO.NETEntityFramework试水——并发[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 ADO.NET Entity Framework 入门示例向导

ADO.NETEntityFramework入门示例向导  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 ADO.NET Entity Framework存取数据库中图片

ADO.NETEntityFramework存取数据库中图片  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 详解ADO.NET Entity Framework 4中枚举的使用

详解ADO.NETEntityFramework4中枚举的使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 ADO.NET Entity Framework存取数据库中的图片

ADO.NETEntityFramework存取数据库中的图片  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 挖掘ADO.NET Entity框架的性能

挖掘ADO.NETEntity框架的性能  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ADON

知识大全 ADO.NET Framework beta 3和Linq

ADO.NETFrameworkbeta3和Linq   以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧