为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/ :)
为DbContextScope添加数据库事务提交完成事件的更多相关文章
- JDBC事务和数据库事务嵌套的讨论 .
首先必须执行con.setAutoCommit(false)方法,将JDBC事务设置为手动提交,否则手动提交con.commit()无效,手动回滚con.rollback()引发SQLExceptio ...
- 4.事务提交过程,交易的基本概念,Oracle交易周期,保存点savepoint,数据库的隔离级别
事务提交过程 事务 基本概念 概念:一个或者多个DML语言组成 特点:要么都成功.要么都失败 事务的隔离性:多个client同一时候操作数据库的时候.要隔离它们的操作, 否则出现:脏读 不可反 ...
- ThinkPHP 数据库操作(六) : 查询事件、事务操作、监听SQL
查询事件 查询事件(V5.0.4+) 从 5.0.4+ 版本开始,增加了数据库的CURD操作事件支持,包括: 查询事件仅支持 find . select . insert . update 和 del ...
- MySql数据库事务正常提交,回滚失败
问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...
- 数据库事务隔离级ORACLE数据库事务隔离级别介绍
本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...
- Sd - 数据库事务
SQL92事务的隔离级别 SQL 标准用三个必须在并行的事务之间避免的现象定义了四个级别的事务隔离. 这些不希望发生的现象是: 脏读(dirty reads):一个事务读取了另一个未提交的 ...
- MySQL 数据库事务与复制
好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适. 最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类. 结合实际工作中碰到的问题,以寻找答案的方式 ...
- 数据库事务中的隔离级别和锁+spring Transactional注解
数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题.ACID首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(At ...
- Atitit 数据库事务实现原理
Atitit 数据库事务实现原理 1.1. 自己在程序中实现事务操作. 如果只是需要事务的话,你自己给mongo操作加上事务功能就可以啦..数据库事务只不过是他自己实现了而已..如果数据库不支持事 ...
随机推荐
- C基础 mariadb处理简单案例
引言 MariaDB 是一款灰常不错开源数据库. 这里直接用它来解决业务问题. 业务需求: 现在数据库中表示按照天分表的. 突然我们需要按照月来处理数据. 例如输入一个玩家id, 查找这个玩家这个月内 ...
- MACBOOK 总是断网怎么办
MACBOOK 连接 wifi 老是断网.焦躁不安 看图,二个方法,第一就搞定,
- 学习1:python输入输出
1. 输出 >>> print "hello world" hello world >>> print 'hello world' hello ...
- FineReport——JS二次开发(下拉框)
下拉框显示多列时,输入的内容检索的内容为显示值整行数据,而不是实际值. 下拉框选择之后,控件显示的是显示值而非实际值. 对于下拉框显示队列,可以有多种方法,但是经过测试大多数方法不适用,检索效率太低, ...
- CMDB (后台管理) CURD 插件
查 a. 基本实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- js 获取html5的data属性
我以前一直以为只能用jquery的data()来获取 哈哈 是我太弱了 <!DOCTYPE html> <html> <head> <title>dat ...
- redis之(十六)redis的cluster集群环境的搭建,转载
最近redis已经比较火了,有关redis的详细介绍,网上有一大堆,我这里只作简单的介绍,然后跟大家一起学习Redis Cluster 3.0的搭建与使用.Redis是一款开源的.网络化的.基于内存的 ...
- WP评论系统更换小结(转)
第三方评论插件 多说 多说是一款追求极致体验的社会化评论框,可以用微博.QQ.人人.豆瓣等帐号登录并评论. 多说具备优质用户体验.速度和稳定性.社会化推荐.建站程序审核整合.垃圾评论过滤等特性. 自定 ...
- JS作用域和ASP(vbs)作用域比较
一.js作用域,先上图: 以上代码执行的效果是,依次弹出 undefined, undefined, a, a,为什么是这样的结果啦?因为JS的作用域为链式作用域. 作用域链: 用VAR声明一个变量时 ...
- 最短路-Bellmanford
简介: 给定一个图和一个源点,求源点到其余点的最短路径,图中有可能存在负权边. 算法步骤 1.初始化:将除源点外的所有顶点的最短距离估计值 dist[v] ← +∞, dist[s] ←0; 2.迭代 ...