HTML5技术

EntityFramework Core并发深挖详解,一纸长文,你准备好看完了吗? - Jeffcky(7)

字号+ 作者:H5之家 来源:H5之家 2017-04-05 14:03 我要评论( )

DbContextExtensions{ SaveChanges( this DbContext context, RefreshConflict refreshMode, int retryCount = 3 ){ if (retryCount = 0 ){ );} return context.SaveChanges(conflicts = conflicts.ToList().ForEac

DbContextExtensions { SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3) { if (retryCount <= 0) { ); } return context.SaveChanges( conflicts => conflicts.ToList().ForEach(tracking => tracking.Refresh(refreshMode)), retryCount); } SaveChanges( this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) => context.SaveChanges( conflicts => conflicts.ToList().ForEach(tracking => tracking.Refresh(refreshMode)), retryStrategy); }

接下来我们来分别演示客户端获胜、数据库获胜以及客户端和数据库合并情况。首先我们放一张数据库默认数据以便对比:

EntityFramework Core并发客户端获胜

var efContext1 = new EFCoreContext(); var efContext2 = new EFCoreContext(); var b1 = efContext1.Blogs.Find(1); var b2 = efContext2.Blogs.Find(1); b1.Name = nameof(efContext1); efContext1.SaveChanges(); b2.Name = nameof(efContext2); b2.Url = ; efContext2.SaveChanges(RefreshConflict.ClientWins);

上述我们看到数据库中的值完全更新为在上下文2中的数据。

EntityFramework Core并发数据库获胜

var efContext1 = new EFCoreContext(); var efContext2 = new EFCoreContext(); var b1 = efContext1.Blogs.Find(1); var b2 = efContext2.Blogs.Find(1); b1.Name = nameof(efContext1); efContext1.SaveChanges(); b2.Name = nameof(efContext2); b2.Url = ; efContext2.SaveChanges(RefreshConflict.StoreWins);

此时我们看到数据库中的值为上下文1中的数据。

EntityFramework Core并发客户端和数据库合并

var efContext1 = new EFCoreContext(); var efContext2 = new EFCoreContext(); var b1 = efContext1.Blogs.Find(1); var b2 = efContext2.Blogs.Find(1); b1.Name = nameof(efContext1); b1.Count = 10; efContext1.SaveChanges(); b2.Name = nameof(efContext2); b1.Count = 11; b2.Url = ; efContext2.SaveChanges(RefreshConflict. MergeClientAndStore);

上述我们看到数据库中的Name和Count是上下文1中的值,而Url则为上下文2中的值。

关于重试机制找到一个比较强大的轮子:https://github.com/App-vNext/Polly 看到一直在更新目前已经支持.net core。看如下加星应该是不错。

没有深入研究该重试机制,就稍微了解了下进行如下重试操作:

public int Commit(Action change, Action<DbUpdateConcurrencyException> handleException, int retryCount = 3) { change(); Policy .Handle<DbUpdateConcurrencyException>(ex => ex.Entries.Count > 0) .Or<ArgumentException>(ex => ex.ParamName == ) .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(10)) .Execute(() => context.SaveChanges()); return context.SaveChanges(); }

同样调用上述UpdateBlog方法,上下文2中数据如下:

readerWriter2.Commit( change: () => { blog2.Name = nameof(readerWriter2); blog2.Count = 4; blog2.Url = ; }, handleException: exception => ............

结果成功更新,利用这个比之前演示的那个更佳,但是发现当执行到这个方法单步执行时会出现如下错误,不知为何:

总结

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • EntityFramework Core不得不注意的性能优化意外收获,你会用错? - Jeffcky

    EntityFramework Core不得不注意的性能优化意外收获,你会用错? - J

    2017-04-05 14:00

  • ASP.NET Core MVC 源码学习:详解 Action 的匹配 - Savorboard

    ASP.NET Core MVC 源码学习:详解 Action 的匹配 - Savorboard

    2017-03-30 18:02

  • ASP.NET Core MVC 源码学习:MVC 启动流程详解 - Savorboard

    ASP.NET Core MVC 源码学习:MVC 启动流程详解 - Savorboard

    2017-03-27 18:01

  • 一份关于组建.NET Core开源团队的倡议书 - 彭泽0902

    一份关于组建.NET Core开源团队的倡议书 - 彭泽0902

    2017-03-13 17:02

网友点评