事务是将一次执行过程当中所涉及的全部操做归入到一个不可分割的执行单元,组成事务的全部操做只有在全部操做均能正常执行的状况下才能提交,只要其中任一操做执行失败,都将致使整个事务的回滚。一句话来讲,就是保证多个操做要么都作,要么都不作。同时一旦事务提交,则其所作的修改会永久保存到数据库。html
基于衡量事务的四个特性,InnoDB 实现事务实际上就是 4 个特性的实现。java
原子性git
隔离性github
持久性sql
既然redo log也须要在事务提交时将日志写入磁盘,为何它比直接将Buffer Pool中修改的数据写入磁盘(即刷脏)要快呢?主要有如下两方面的缘由:
(1)刷脏是随机IO,由于每次修改的数据位置随机,但写redo log是追加操做,属于顺序IO。
(2)刷脏是以数据页(Page)为单位的,MySQL默认页大小是16KB,一个Page上一个小修改都要整页写入;而redo log中只包含真正须要写入的部分,无效IO大大减小。
一致性数据库
现代软件架构随着业务领域划分为多个微服务,共同组成了复杂的软件系统。而从数据库层面来看,随着数据量的爆发,不得不采用分库分表的方式,下降数据库的压力。这样,就形成多个服务依赖不一样的数据库,那么在同时操做的时候,如何保证事务?这就是分布式事务。缓存
简而言之,分布式事务就是一个大的事务由不一样的子事务组成,这些小的事务操做分布在不一样的服务器节点上面,属于不一样的微服务,分布式事务须要保证同一事务下的子事务要么所有成功,要么所有失败,即保证数据的最终一致性。服务器
在这篇不想用太大的篇幅说一些概念上的东西,可是要说 RocketMQ 的分布式事务实现,因此在这里顺便提一下当前分布式事务的集中解决方案:架构
两阶段提交(2PC) 是 Oracle Tuxedo 系统提出的 XA 分布式事务协议的其中一种实现方式,参考 《分布式事务之两阶段提交(2PC)》 。并发
TCC 是基于尝试、确认、取消来实现分布式事务的,想了解更多,参考 《分布式事务之补偿事务( TCC )》 。
本地消息表 方案最初是ebay提出的,核心是将须要分布式处理的任务经过消息日志的方式来异步执行。消息日志能够存储到本地文本、数据库或消息队列,再经过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,经过对帐系统对过后问题的处理。
除了上述外,还有一些解决方案,好比阿里 SEATA ,SAGA方案和最大努力通知...感兴趣同窗们能够自行了解,固然还有咱们这篇要说的 MQ 事务。
RocketMQ 是阿里开源的一款高性能、高吞吐量的分布式消息中间件,基于消息异步方式提供了对分布式事务的支持,实现事务最终一致性。
下面是 RocketMQ 事务消息的基本流程交互图:
如图其中分为两个流程:正常事务消息的发送及提交、事务消息的补偿流程。
1.事务消息发送及提交:
(1) 发送 half 消息。
(2) 服务端响应消息写入结果。
(3) 根据发送结果执行本地事务(若是写入失败,此时half消息对业务不可见,本地逻辑不执行)。
(4) 根据本地事务状态执行 Commit 或者 Rollback( Commit 操做生成消息索引,消息对消费者可见)
流程图以下:
2.补偿流程:
(1) 对没有 Commit/Rollback 的事务消息( pending 状态的消息),从服务端发起一次“回查”
(2) Producer收到回查消息,检查回查消息对应的本地事务的状态
(3) 根据本地事务状态,从新Commit或者Rollback
其中,补偿阶段使用定时器回查方式用于解决消息 Commit 或者 Rollback 发生超时或者失败的状况。
如上,小伙伴们应该对 RocketMQ 的事务消息有了必定的了解,下面看下如何在开发场景下如何使用。
发送事务消息时和普通的消息区别是,本身要新建一个 TransactionMQProducer
和对应的一个 TransactionListener
的实现。
this.producer = new TransactionMQProducer(config.getGroup()); this.producer.setNamesrvAddr(config.getNameServer()); this.producer.setExecutorService(config.getExecutorService()); this.producer.setTransactionListener(config.getTransactionListener());
TransactionListener
实现 TransactionListener
接口的两个方法:
executeLocalTransaction(Message message, Object o)
checkLocalTransaction(MessageExt messageExt)
代码详见 👀 : https://github.com/wangning1018/rocketmq-transaction-message-demo
欢迎访问 我的博客 获取更多知识分享。