原标题:基于数据库的事务消息解决分布式事务方案
这两把剑应该不是普通地凡铁。它们都有生命……或说。它们都有某种灵性。说是剑灵也不为过。 当叶扬回到自己别墅时,苏小暖和孙艺维并没有在家里,想必是去上课了。一想到上课,叶扬自己都忍不住想要吐槽,不是说好成了正常人之后就要好好上课,做个好学生吗。怎么感觉自己这些天还是有着诸多的时间没有去上课啊,虽然不是那种一走就是一整年,但是这时常翘课也不是什么好事吧。 魔鬼训练那段时间,小舞每次疲倦了。唐三都会帮她揉揉腿。玄天功内力和魂力终究还是有些区别的。其中属于道家的医疗作用就是魂力所不具备的,总体来说,魂力偏于霸道。而玄天功则是中正平和。 转载请注明出处:http://www.cnblogs.com/lizo/p/8516502.html 当单库已不能支撑当前业务的时候,我们往往都考虑进行分库(横向拆分或者纵向拆分)。但分库有个无法回避的问题,就是事务问题。网上有很多分布式事务解决方案,例如XA,TCC等,但是最常用,也是改造成本最低就是使用最终一致性来保证分布式事务。 本篇文章将使用数据库的来达到最终一致性的实现方案。 注:以下有些内容是在使用事务消息(无论是基于数据库还是基于消息队列)应该考虑的地方。 所谓基于数据库的事务消息,其实很好理解,就是在数据库中创建一个类似消息队列的表,用于保存事务消息。在拆分前,一个事务中,有多个主库的数据操作。如下图, 但是在拆分数据库后,有业务被拆分到分库中去了,这样,原有的单库事务被打破,但是通过把拆分出去的业务使用一个事务消息来代替(事务消息表也是在主库中,所以这里还是单库事务),后续再通过其他方式去执行该事务消息所对应的业务逻辑即可,这样,就可以达到最终一致性,如下图 前面说到了,事务消息需要一个处理器来进行执行事务消息所对应的业务逻辑。事务处理器应该是顺序的去读取并执行的。 设想一个场景:当出现某一条消息处理失败,如果执行器要等当前消息执行成功才继续往后执行(甚至该消息永远不会处理成功),那么会影响后续消息的执行,导致整个系统出现问题。 因此,消息处理器即要保证消息处理尽可能处理快,又能保证消息最终能执行成功。 在流水执行器中必须设置2个任务: 设想,如果分库业务执行成功(更新分库),然后去更新消息状态(主库),这样,又是一个夸库事务,所以,得想其他办法来避免,最简单的方法,就是在分库里面也建一个消息表,保存处理的成功的消息。这样,通过对比主库和分库的消息表,就知道哪些事务消息没有执行成功 前面介绍了,消息处理器的核心功能就: 为了完成上面功能,需要消息处理任务和消息校验任务,通过定时调度任务来触发这2个任务(例如,5s触发一次) 消息处理任务就是通过扫描待处理的消息,然后通知业务系统执行。 再次强调,消息处理任务不会管消息是否执行成功。都是按照消息队列表顺序执行下去。 校验任务就是比较主库和分库中的消息记录(主库中记录的所有流水,分库中记录的执行成功的流水),对执行未成功的消息发起重试,如果多次重试失败则发出告警,需要人工介入。 使用消息中间件,一般都需要在代码中显示的编写提交中间件事务消息的代码,类似下面 但在实际项目中,事务的传播性的问题(spring 的事务注解是支持事务的传播性),就需要修改业务代码。但使用基于数据库的消息队列就没有这个问题 所以在既有代码改造上(特别是复杂系统中),使用数据库的事务消息可以减少代码的改动 我们知道,在使用消息中间件的时候,都需要实现一个回调接口,当事务消息长时间没有commit的时候,会调用该接口来确认是否需要commit(例如发送消息成功,但是在commit的时候网络不可用)。而基于数据局的事务消息队列就没有这个问题 基于数据库的事务消息也有一个比较明显的缺点: 基于数据库和基于消息队列的事务消息的基本思路都一样,使用最终一致性来避免分布式事务带来的额外系统复杂性和代码开销。基于数据库的事务消息在既有业务改造中,代码变动较小,也不需要额外的引入消息中间件,但是带来的问题就是对数据库更多的访问。而基于消息中间件的问题就是如何避免在与消息中间件交互的出现问题的时候如何应对。当然,以上只是我个人理解,如果系统有什么设计不合理或者有改进的地方,欢迎讨论。
“是啊,而且小丑皇被打中了怎么可能还能施展皇牌飞刀。”素娜等人一脸惊疑,不解之色。概述
比较常用的就是使用消息中间件(RabbitMq,RocketMq),通过事务消息来解决最终一致性。参考https://zhuanlan.zhihu.com/p/25933039?utm_source=tuicool&utm_medium=referral。名词解释
基于数据库的事务消息
事务消息
事务消息执行器
消息执行的特性
如何确认消息已执行成功
消息处理器基本框架
消息处理任务
消息校验任务
和基于消息中间件的事务消息比较
相同点
不同点
消息事务的提交
public boolean transaction(String text){
try {
发送事务消息
执行本地事务
提交事务消息
return true;
} catch (TmcException e) {
return false;
}
}
@Transactional
public void publishAS(String text){
执行本地事务逻辑
插入事务消息
}
不需要回调check
更多的数据库访问资源
小结
编辑:道公邓乙
发布时间:2019-02-18 00:00:00
当前文章:http://neomi.cn/kongwang/2866.html
荣耀棋牌有安卓版吗 趣友麻将拼十作弊器 捕鱼现金版注册送分 7k7k游戏和手机版下载 3d推荐号码今晚预测 广东十一选五158计划网 神钢机器人资料 玄幻都市之无敌大熊猫
27831 30342 25149 37045 93526 4306268659 90994 45170
责任编辑:公成龙