转载请注明出处:http://www.cnblogs.com/lizo/p/8516502.html

概述

当单库已不能支撑当前业务的时候,我们往往都考虑进行分库(横向拆分或者纵向拆分)。但分库有个无法回避的问题,就是事务问题。网上有很多分布式事务解决方案,例如XA,TCC等,但是最常用,也是改造成本最低就是使用最终一致性来保证分布式事务。
比较常用的就是使用消息中间件(RabbitMq,RocketMq),通过事务消息来解决最终一致性。参考https://zhuanlan.zhihu.com/p/25933039?utm_source=tuicool&utm_medium=referral。

本篇文章将使用数据库的来达到最终一致性的实现方案。

名词解释

  • 主库-拆分前,业务访问的数据库
  • 分库-拆分后,部分业务数据放入到分库中

注:以下有些内容是在使用事务消息(无论是基于数据库还是基于消息队列)应该考虑的地方。

基于数据库的事务消息

事务消息

所谓基于数据库的事务消息,其实很好理解,就是在数据库中创建一个类似消息队列的表,用于保存事务消息。在拆分前,一个事务中,有多个主库的数据操作。如下图,

但是在拆分数据库后,有业务被拆分到分库中去了,这样,原有的单库事务被打破,但是通过把拆分出去的业务使用一个事务消息来代替(事务消息表也是在主库中,所以这里还是单库事务),后续再通过其他方式去执行该事务消息所对应的业务逻辑即可,这样,就可以达到最终一致性,如下图

事务消息执行器

前面说到了,事务消息需要一个处理器来进行执行事务消息所对应的业务逻辑。事务处理器应该是顺序的去读取并执行的。

设想一个场景:当出现某一条消息处理失败,如果执行器要等当前消息执行成功才继续往后执行(甚至该消息永远不会处理成功),那么会影响后续消息的执行,导致整个系统出现问题。

因此,消息处理器即要保证消息处理尽可能处理快,又能保证消息最终能执行成功。 在消息执行器中必须设置2个任务:

  • 第一个任务,消息处理任务,已最快的速度执行消息,如果消息处理失败了,跳过该消息继续执行后面的消息。
  • 第二个任务,消息校验任务,这个任务就是顺序检查消息,保证所有消息都执行成功,如果失败,进行重试,多次重试失败以后发出告警以让人工介入处理。 如下图

注:上图左边那个是消息队列及其处理状态

消息执行的特性

  • 延迟处理性。消息不是实时处理的,而是用过消息执行器来异步执行的。因此,如果在原有逻辑中,需要特别注意后续流程对该消息处理结果是不是有实时依赖性(例如后续业务逻辑中会使用该消息处理结果来做一些计算等)。
  • 处理无序性。由于消息不一定是顺序执行的,所有保证即使后生成的消息先执行,也不能出现问题。
  • 最终成功性。对每条插入的消息,保证该条消息一定要能执行成功

如何确认消息已执行成功

设想,如果分库业务执行成功(更新分库),然后去更新消息状态(主库),这样,又是一个夸库事务,所以,得想其他办法来避免,最简单的方法,就是在分库里面也建一个消息表,保存处理的成功的消息。这样,通过对比主库和分库的消息表,就知道哪些事务消息没有执行成功

消息处理器基本框架

前面介绍了,消息处理器的核心功能就:

  • 获取消息,并把消息发送给业务放处理
  • 保证消息执行的成功

为了完成上面功能,需要消息处理任务和消息校验任务,通过定时调度任务来触发这2个任务(例如,5s触发一次)

消息处理任务

消息处理任务就是通过扫描待处理的消息,然后通知业务系统执行。

再次强调,消息处理任务不会管消息是否执行成功。都是按照消息队列表顺序执行下去。

消息校验任务

校验任务就是比较主库和分库中的消息记录(主库中记录的所有消息,分库中记录的执行成功的消息),对执行未成功的消息发起重试,如果多次重试失败则发出告警,需要人工介入。

和基于消息中间件的事务消息比较

相同点

  • 都是采用异步确保最终一致性:
  • 可以控制异步执行消息的速率,可以利用RPC调用的负载均衡
  • 消息处理都必须支持重试和幂等性
  • 事务消息异步执行失败,都没办法回滚产生事务消息的事务

不同点

消息事务的提交

使用消息中间件,一般都需要在代码中显示的编写提交中间件事务消息的代码,类似下面

public boolean transaction(String text){try {发送事务消息执行本地事务提交事务消息return true;} catch (TmcException e) {return false;}
}

但在实际项目中,事务的传播性的问题(spring 的事务注解是支持事务的传播性),就需要修改业务代码。但使用基于数据库的消息队列就没有这个问题

@Transactional
public void publishAS(String text){   执行本地事务逻辑插入事务消息
}

所以在既有代码改造上(特别是复杂系统中),使用数据库的事务消息可以减少代码的改动

不需要回调check

我们知道,在使用消息中间件的时候,都需要实现一个回调接口,当事务消息长时间没有commit的时候,会调用该接口来确认是否需要commit(例如发送消息成功,但是在commit的时候网络不可用)。而基于数据局的事务消息队列就没有这个问题

更多的数据库访问资源

基于数据库的事务消息也有一个比较明显的缺点:

  • 占用更多的数据库空间和数据库访问资源
  • 需要额外编写DAO层代码

小结

基于数据库和基于消息队列的事务消息的基本思路都一样,使用最终一致性来避免分布式事务带来的额外系统复杂性和代码开销。基于数据库的事务消息在既有业务改造中,代码变动较小,也不需要额外的引入消息中间件,但是带来的问题就是对数据库更多的访问。而基于消息中间件的问题就是如何避免在与消息中间件交互的出现问题的时候如何应对。当然,以上只是我个人理解,如果系统有什么设计不合理或者有改进的地方,欢迎讨论。

转载于:https://www.cnblogs.com/lizo/p/8516502.html

基于数据库的事务消息解决分布式事务方案相关推荐

  1. 搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务

    搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocke ...

  2. 启发:从MNS事务消息谈分布式事务

    启发:从MNS事务消息谈分布式事务 事务消息本质上解决的问题是业务系统与消息系统之间的事务问题(跨系统分布式事务),其基本原理即两阶段提交以及最终一致性保障.最近看了下阿里云mns事务消息的实现原理, ...

  3. 分布式事务 - 如何解决分布式事务问题?

    分布式事物 - 如何解决分布式事务问题? 面试题 分布式事务了解吗?你们是如何解决分布式事务问题的? 面试官心理分析 只要聊到你做了分布式系统,必问分布式事务,你对分布式事务一无所知的话,确实会很坑, ...

  4. LCN分布式事务框架解决分布式事务一致性问题

    LCN分布式事务框架 框架介绍 LCN分布式事务框架其本身并不创建事务,而是基于对本地事务的协调从而达到事务一致性的效果. 核心步骤 创建事务组 是指在事务发起方开始执行业务代码之前先调用TxMana ...

  5. 分布式事务模型--基于消息的分布式事务

    本文来说下分布式事务模型之基于消息的分布式事务 文章目录 概述 基于消息的分布式事务 基于事务消息的分布式事务 基于本地消息的分布式事务 特点剖析 本文小结 概述 事务是一组不可分组的操作集合,这些操 ...

  6. 消息队列中:消息可靠性、重复消息、消息积压、利用消息实现分布式事务

    点击下方"Java编程鸭"关注并标星 更多精彩 第一时间直达 一.如何确保消息不丢失? 1.检测消息丢失的方法 可以利用消息队列的有序性来验证是否有消息丢失.在Producer端给 ...

  7. rabbitmq 查询版本_基于rabbitmq解决分布式事务

    分布式事务要解决的问题是保证二个数据库数据的一致性,本地事务ACID属于刚性事务,基于CAP理论,分布式事务的核心要点柔性事务,最终一致性. 基于rabbitmq解决分布式事务要点如下 生产者采用发送 ...

  8. .Net Core with 微服务 - 使用 AgileDT 快速实现基于可靠消息的分布式事务

    前面对于分布式事务也讲了好几篇了(可靠消息最终一致性分布式事务 - TCC分布式事务 - 2PC.3PC https://github.com/kklldog/AgileDT 开源不易,大家多多 ✨✨ ...

  9. spring boot 事务_一个基于 RabbitMQ 的可复用的分布式事务消息架构方案!

    作者:Throwable | https://www.cnblogs.com/throwable/p/12266806.html 前提 分布式事务是微服务实践中一个比较棘手的问题,在笔者所实施的微服务 ...

最新文章

  1. emacs参考资料整理
  2. 无线路由器配置不佳 可耗净手机电量
  3. Android判断当前的android设备是否处于联网状态
  4. CentOS 7.0卸载自带的mariadb
  5. c语言将0到1十等分放入数组,C语言课程设题计目汇总.doc
  6. Python excle数据读写
  7. 频繁使用花呗、借呗、微粒贷、京东白条会影响在银行的信用吗?
  8. 单片机启动流程(以STM32为例)
  9. Atitit.工作流系统的本质是dsl 图形化的dsl  4gl
  10. rbf神经网络python预测代码_RBF神经网络预测
  11. html5 指南针,14.html5 作业 简单移动端-指南针 用 canvas 画一下.
  12. 《炬丰科技-半导体工艺》采用湿法工艺制备的具有自洁表面的黑硅
  13. IP欺骗攻击原理及如何修改IP
  14. 手写Spring-第十六章-旋转吧雪月花!用三级缓存解决循环依赖
  15. 在线教育项目技术笔记1
  16. 苹果将推出自助维修计划
  17. 手机上的python怎么运行,python在手机上怎么操作
  18. 某A的工口游戏创作者体验记(下)
  19. 发现今年是阿里和腾讯这么多年来最大规模的校招
  20. 认识wang域名吗?从wang域名使用情况分析投资价值

热门文章

  1. S2SH CRUD 整合
  2. 【转载】程序员技术练级攻略
  3. Spring中Bean的概念
  4. 5 useMemouseCallback
  5. 手机两列布局,正方形
  6. angularjs初始化时不显示模板内容, 不显示html, 不显示template
  7. string类的实现(构造函数,析构函数,运算符重载)
  8. oracle索引建立
  9. 求大神解决下这个题目!做好请发到308960728@qq.com
  10. JNDI(datasource)在tomcat,JBOSS下的spring+quartz配置