zoukankan      html  css  js  c++  java
  • 为DbContextScope添加数据库事务提交完成事件

        使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gueddari对此做了深入研究和优秀的工作并且写了一篇优秀的文章,为了方便更多的童鞋学习,我已将其翻译为中文系列 :

    在EntityFramework6中管理DbContext的正确方式

        当然,在使用Mehdi El Gueddari为我们提供的DbContextScope组件时,任然会遇到一些比较棘手的问题,比如:

       

                using (var scope = _dbContextScopeFactory.Create())
                {
                    var db = scope.DbContexts.Get<RentalServiceDbContext>();
    
                    var bookingInfo = db.BookingInfoes.Load(bookingId);
    
                    //调用bookingInfo处理一些操作
    
    
                    //当满足一定的条件,发布一个事件,事件的订阅者可以订阅该信息并处理
                    if (bookingInfo.Status == BookingStatus.Ordered)
                    {
                        _roomEventSvc.PublishRoomEvent(bookingInfo.RoomId, bookingInfo.Id, RoomEventType.BookingRoom);
                    }
               
                    //提交数据库事务
                    scope.SaveChanges();
                }

        有可能我们发布的事件会被很快订阅者处理,甚至在我们提交事务之前!但问题就在于事件的订阅者很可能假定我们已经提交事务了!

        当然,我们很可能想到的最简单的处理问题的方法就是 将 发布事件的那个代码片段移到 提交 事务后面。确实可以这样,就这个Demo来说,这样处理简单方便。但我们可能面临更多复杂的场景,比如这个服务方法被嵌套在另外一个服务方法内部调用,而且 事务也自动升级为使用外部服务的 事务,那么这个时候上面的简单处理方法就失效了!

         最好的办法就是我们能在 DbContextScope提交事务后,插入一段我们自己的代码逻辑来实现我们的业务逻辑功能,很显然,为DbContextScope增加一个提交事务事件即可,然后就像下面这样使用:

         

                using (var scope = _dbContextScopeFactory.Create())
                {
                    var db = scope.DbContexts.Get<RentalServiceDbContext>();
    
                    var bookingInfo = db.BookingInfoes.Load(bookingId);
    
                    //调用bookingInfo处理一些操作
    
    
                    //当满足一定的条件,发布一个事件,事件的订阅者可以订阅该信息并处理
                    if (bookingInfo.Status == BookingStatus.Ordered)
                    {
                        //保证我们的PublishRoomEvent方法在事务提交后执行
                        scope.DbContexts.TransactionCommitted += (sender, args) =>
                        {
                            _roomEventSvc.PublishRoomEvent(bookingInfo.RoomId, bookingInfo.Id, RoomEventType.BookingRoom);
                        };
                    }
               
                    //提交数据库事务
                    scope.SaveChanges();
                }

             其实,只需要几行代码就可以为DbContextScope增加事务提交事件,在这儿就不具体描述了!详见这儿 https://github.com/mehdime/DbContextScope/pull/54

             需要dll的童鞋可以在nuget上面进行下载  https://www.nuget.org/packages/UOKO.DbContextScope/   :)

        

     

  • 相关阅读:
    一本通1621轻拍牛头
    2.23模拟赛
    一本通1618越狱
    P2280 [HNOI2003]激光炸弹
    P4513 小白逛公园
    P2165 [AHOI2009]飞行棋
    P1877 [HAOI2012]音量调节
    P2023 [AHOI2009]维护序列
    P2253 好一个一中腰鼓!
    P2434 [SDOI2005]区间
  • 原文地址:https://www.cnblogs.com/JefferyZhang/p/8205227.html
Copyright © 2011-2022 走看看