分布式事务及解决方案

1、 经典事务

经典事务,是指传统的单机数据库事务,必须具备ACID原则:

  • 原子性(A)
    所谓的原子性就是说,在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。对于事务在执行中发生错误,所有的操作都会被回滚,整个事务就像从没被执行过一样。
  • 一致性(C)
    事务的执行必须保证系统的一致性,就拿转账为例,A有500元,B有300元,如果在一个事务里A成功转给B50元,那么不管并发多少,不管发生什么,只要事务执行成功了,那么最后A账户一定是450元,B账户一定是350元。
  • 隔离性(I)
    所谓的隔离性就是说,事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。
  • 持久性(D)
    所谓的持久性,就是说一单事务完成了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停电,系统宕机也是如此。

2、 分布式事务

  1. 什么是分布式事务
    事务发生时,其中的参与者主要包含:应用服务、数据库。在经典事务中,无论是应用服务还是数据库都是单机部署,因此可以完全遵循ACID原则。但是现在主流的系统架构都是SOA的架构,以及现在日渐火热的微服务架构中,应用及数据库都会采用分布式集群部署。于是就产生了跨数据源或者跨服务的事务,这就是分布式事务。
  2. 解决分布式事务的思路
    在分布式系统中,就不得不面对CAP的理论。

CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的,他指出WEB服务无法同时满足一下3个属性:
• 一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)
• 可用性(Availability) : 每个操作都必须以可预期的响应结束
• 分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成

具体地讲在分布式系统中,在任何数据库设计中,一个Web应用至多只能同时支持上面的两个属性。显然,任何横向扩展策略都要依赖于数据分区。因此,设计人员必须在一致性与可用性之间做出选择。

而面对高并发的互联网行业,高可用显然会比一致性要重要的多,但是一致性也是不可抛弃的,如何解决这一矛盾?这个时候,大神们有总结出了BASE理论:
• Basically Available(基本可用)
• Soft state(软状态)
• Eventually consistent(最终一致性)
BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

  1. 柔性事务和刚性事务
    刚性事务:严格遵循ACID原则的事务, 例如单机环境下的数据库事务。
    柔性事务:指遵循BASE理论(基本可用,最终一致)的事务, 通常用在分布式环境中
    因为分布式事务的特点,只能采用柔性事务,常用的柔性事务解决方案有:

两阶段提交(Two Phase Commit, 2PC)
 有成熟的解决框架,实现简单。
 资源锁定周期长,执行效率低,不适合高并发场景
 故障恢复困难
TCC补偿型事务(Try - Confirm - Cancel)
 实现很复杂,开发成本高
 资源锁定粒度小,执行效率高
 强隔离性,严格的数据一致性
 事务执行周期短
异步确保,基于可靠MQ服务
 实现较为复杂,成本略高
 对MQ的可靠性要求高
 事务执行周期长
最大努力通知
 实现简单,成本低
 不保证最终一致

3、 柔性事务的实现方案

  1. 两阶段提交(2PC)
    原理:
    两阶段提交,基于XA协议,以及JTS协议JTA接口。
    XA协议指的是TM(事务管理器)和RM(资源管理器)之间的接口,由Tuxedo提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。XA实现分布式事务的原理如下:

正常情况
在这里插入图片描述
异常情况
在这里插入图片描述
在JavaEE平台下,WebLogic、Webshare等主流商用的应用服务器提供了JTA的实现和支持。而在Tomcat下是没有实现的,但是可以借助第三方的框架Jotm、Automikos等来实现,两者均支持spring事务整合。
缺点
 两阶段提交中的第二阶段, 协调者需要等待所有参与者发出yes请求, 或者一个参与者发出no请求后, 才能执行提交或者中断操作. 这会造成长时间同时锁住多个资源, 造成性能瓶颈, 如果参与者有一个耗时长的操作, 性能损耗会更明显.
 实现复杂, 不利于系统的扩展, 不推荐.现在几乎很少使用

  1. TCC(Try - Confirm - cancel)
    原理:
    TCC是基于业务层面的事务定义。锁粒度完全由业务自己控制。它本质是一种补偿的思路。它把事务运行过程分成 Try、Confirm / Cancel 两个阶段。在每个阶段的逻辑由业务代码控制。这样就事务的锁粒度可以完全自由控制。业务可以在牺牲隔离性的情况下,获取更高的性能。

Try 阶段
Try :尝试执行业务
 完成所有业务检查( 一致性 )
 预留必须业务资源( 准隔离性 )
Confirm / Cancel 阶段:
Confirm :确认执行业务
 真正执行业务
 不做任务业务检查
 Confirm 操作满足幂等性
Cancel :取消执行业务
 释放 Try 阶段预留的业务资源
 Cancel 操作满足幂等性
 Confirm 与 Cancel 互斥
原理图:
在这里插入图片描述
实例
在电商网站中,一个经典的案例是这样的:用户下单,基于订单系统实现,操作订单表;同时下单需要对商品进行减库存操作,在库存系统完成;同时还要对用户进行积分奖励,在用户中心完成。这样就出现了分布式事务。
在这里插入图片描述
优缺点
优点:
 TCC的try、confirm等操作全部有用户定义,因此锁定粒度由用户自由控制。各个资源独立锁定,分别提交、释放,无需等待对方。失败后是执行cancel中的补偿型操作即可。
 事务执行效率高,时间短
 能够保证严格的数据一致性。
缺点:
 正是因为需要用户编写所有的try、confirm、cancel操作,另外还有重试、幂等的要求,日志的记录等,实现复杂度较高,开发成本增加。
目前有一些开源的TCC框架:
TCC-transaction: https://github.com/changmingxie/tcc-transaction
spring-cloud-rest-tcc: https://github.com/prontera/spring-cloud-rest-tcc
happylifeplat-transaction: https://github.com/yu199195/happylifeplat-transaction
使用场景
对一致性要求较高,事务时效性比较敏感的业务。

  1. 异步确保
    这种实现方式的思路,其实是源于ebay,后来通过支付宝等公司的布道,在业内广泛使用。其基本的设计思想是将远程分布式事务拆分成一系列的本地事务。如果不考虑性能及设计优雅,借助关系型数据库中的表即可实现。

业务与消息耦合:
在这里插入图片描述
在这个实现中,将分布事事务,拆分成了主动方事务和被动方事务,通过mq进行异步通知来确保最终的数据一致性。
优点:
 与tcc相比,实现方式较为简单,开发成本低。
缺点:
据一致性完全依赖于消息服务,因此消息服务必须是可靠的。
 需要处理被动业务方的幂等问题
 被动业务失败不会导致主动业务的回滚
 业务与消息服务耦合
业务与消息的解耦
刚才的实现中,业务方在进行业务处理的同时,还需要对消息数据进行持久化,代码耦合,不方便以后的维护。我们可以采用下面的模式,将消息与业务解耦:
在这里插入图片描述
优点:
 消息系统与业务系统解耦
 消息系统可以独立存储、独立伸缩
缺点:
 每次消息发送,需要两次请求
 业务处理系统,需要提供业务状态查询接口
使用场景:
对事务一致性的时效要求不高的业务。例如跨行转账,支付宝余额宝转账。

  • 最大努力通知
    原理
    最大努力通知主要用于对于事务的一致性不是特别敏感的事务,实现事务的弱一致性。可以通过消息中间件实现。与前面异步确保型操作不同的一点是, 在消息由MQ Server投递到消费者之后, 允许在达到最大重试次数之后正常结束事务.
  • 主业务完成后,通过mq通知被动业务(允许消息丢失)
  • 通知失败后主动方 按照一定的时间阶梯进行消息发送重试,直到超过最大重试次数为止
  • 主动方提供业务查询接口,以便被动方后续进行通知失败后的补偿,恢复丢失消息。

分布式事务及解决实战

分布式事务解决方案Seata入门介绍
分布式事务解决方案Seata搭建
分布式事务解决方案Seata实战-AT模式
分布式事务解决方案Seata集群搭建
分布式事务解决方案Seata实战-TCC模式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员劝退师-TAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值