你的位置:首页 > 软件开发 > ASP.net > C# Entity Framework并发处理

C# Entity Framework并发处理

发布时间:2016-11-23 20:00:42
原网站:C# Entity Framework并发处理在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制。从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都为并发控制提供好良好的支持方案。 ...

原网站:C# Entity Framework并发处理

软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制。从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都为并发控制提供好良好的支持方案。

 

C# Entity Framework并发处理

 回到目录

 

三、Entity Framework 悲观并发

在一般的开发过程中,最常用的是悲观并发处理。.NET 提供了Lock、Monitor、Interlocked 等多个锁定数据的方式,它可以保证同一个表里的对象不会同时被多个客户进行修改,避免了系统数据出现逻辑性的错误。

使用悲观并发虽然能有效避免数据发生逻辑性的错误,但使用 lock 等方式锁定 Update 方法的操作,在用户同时更新同一数据表的数据,操作就会被延时或禁止。在千万级 PV 的大型网络系统当中使用悲观并发,有可能降低了系统的效率,此时可以考虑使用乐观并发处理。

 回到目录

 

四、Entity Framework 乐观并发

为了解决悲观并发所带来的问题,ADO.NET Entity Framework 提供了更为高效的乐观并发处理方式。相对于LINT to SQL , ADO.NET Entity Framework 简化了乐观并发的处理方式,它可以灵活使用合并数据、保留初次输入数据、保留最新输入数据等方式处理并发冲突。

根据操作结果可以看到,在Entity Framework的默认环境情况下,系统会使用合并方式处理并发,把输入数据的所有修改值都保存到当前上下文当中,并同时修改数据库当中的值。

C# Entity Framework并发处理

 

4.1.2 删除与更新操作同时运行

Entity Framework 能以完善的机制灵活处理同时更新同一对象的操作,但一旦删除操作与更新操作同时运行时,就可能存在逻辑性的异常。例如:两个客户端同时加载了同一个对象,第一个客户端更新了数据后,把数据再次提交。但在提交前,第二个客户端已经把数据库中的已有数据删除。此时,上下文中的对象处于不同的状态底下,将会引发 OptimisticConcurrencyException 异常。

观察运行测试结果,当运行 Delete 方法,对象已经在数据库中被删除,对象的EntityState处于 Detached 状态。此时使用 SaveChanges 保存更新数据时,引发了OptimisticConcurrencyException 异常。在捕获异常,把对象状态更改为 Added ,再使用SaveChanges保存数据,数据就能顺利地保存到数据库中。但值得留意,因为对象是在删除后重新加载的,所以对象的 Id 也会被同步更新。

C# Entity Framework并发处理

以合并数据的方式处理并发冲突固然方便快节,但在业务逻辑较为复杂的系统下并不适合使用此处理方式。比如在常见的Order、OrderItem的表格中,OrderItem 的单价,数量会直接影响Order的总体价格,这样使用合并数据的方式处理并发,有可能引起逻辑性的错误。此时,应该考虑以其他方式处理并发冲突。

 

4.2 当发生数据并发时,保留最新输入的数据

要验证输入对象的属性,必须先把该属性的 ConcurencyMode 设置为 Fixed,这样系统就会实时检测对象属性的输入值 。

观察测试结果,可见当RefreshMode状态为ClientWins时,系统将会保存上下文当中的对象属性,使用此方法可以在发生并发异常时保持最新输入的对象属性。

C# Entity Framework并发处理

 

4.3 当发生数据并发时,保留最初输入的数据

把对象属性的 ConcurencyMode 设置为 Fixed 后,同时更新该属性,将会激发 OptimisticConcurrencyException 异常。此时使用 ObjectContext.Refresh (RefreshMode,object) 刷新上下文中该对象的状态,当 RefreshMode 为 StoreWins 时,系统就会把数据源中的数据代替上下文中的数据。

观察测试结果,可见当 RefreshMode 状态为 StoreWins 时,系统将会以数据源中的数据代替上下文当中的对象属性。在业务逻辑较为复杂的的系统当中,建议使用此方式处理并发异常。

C# Entity Framework并发处理

回到目录

 

五、回顾 LINQ to SQL 并发处理的方式

Entity Framework 当中简化了并发处理的方式,然而温故而知新,LINQ to SQL 中并发处理所使用的方式也值得回顾一下。下面将与大家一起回顾一下 LINQ to SQL 当中并发处理的方式。

例子当中使用 RefreshMode.KeepChanges 的方式处理并发,系统会保存最新输入的数据。观察测试结果,当系统发生第一次更新时,数据成功保存到数据库当中。在 DataContext 未释放前,再次输入数据,引发了ChangeConflictException异常。在捕获此并发异常后,系统以 RefreshMode.KeepChanges 方式进行处理,最后新输入的数据成功保存到数据库当中。

C# Entity Framework并发处理

回到目录

 

六、结合事务处理并发冲突

Entity Framework 中已经有比较完善的机制处理并发,但使用乐观性并发处理数据,一旦多个客户端同时更新同一张表格的同一个对象时,将会激发 OptimisticConcurrencyException 异常,系统必须预先定制好处理方案对此并发异常进行处理。结合事务使用乐观性并发共同处理数据,是一个比较高效的数据管理方式。事务能对数据的更新进行检测,一旦发现异常,便会实现回滚。本文会使用常用的隐式事务 TransactionScope 作为例子进行介绍,对事务的详细介绍,可以参考 “C#综合揭秘——细说事务”。

观察测试结果,当系统发生并发异常时,数据库只会保留首次输入的更新值。值得注意的是:使用此数据处理方式与悲观并发方式最大区别在于,传统的悲观并发处理方式不允许同一时刻有多个客户端处理同一个数据表中的相同对象,但因为客观因数的影响,系统难以仔细辨认客户同时进行修改的是否同一个数据项,所以基本的做法是使用锁把更新对象进行锁定。但如此一来,无论客户同时更新的是否同一个数据项,操作都将会被延时或禁止。换句话说,无论需要更新的是相同对象还是不同对象,客户端都不能同时更新同一个数据表。若使用此乐观并发方式,系统允许多个客户端同时处理同一个数据表。如果所处理的是数据表中的不同对象,操作可以顺利地进行而不会相互影响。如果所处理的是数据表中的相同对象,操作将会保存第一次输入的对象值。

C# Entity Framework并发处理

 

 回到目录

总结

并发话题与get='_blank'>线程、进程等其他话题有所不同,它并没有复杂的类和方法。处理并发来来去去都是简单的几行代码,它所重视的是并发异常发生后所带来的后果与处理方式。与中国传统的太极相似,并发只重其意,不重其招,只要深入地了解其过程,考虑其可能带来的问题后,你便可以对其收发自如。 

原标题:C# Entity Framework并发处理

关键词:C#

C#
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录