全国学渣代表  

分布式事务

什么是分布式事务?

就是在不同服务器上每个机器上都有一个数据库,当对不同数据库进行操作的时候采取的原子性、一致性、隔离性和持久性。

X/OPEN组织规范

因为分布式事务的衍生,因此X/OPEN组织定义了一套规范,并且各个厂商都遵循该协议 Oracle mysql sqlSever

先了接一些基本名词 xa 、dtp 、jta、rm 、ap 、tm

dtp 就是xopen定义的一套规范模型

javaEE也是这样java中的规范叫JTA

AP(Application Program):也就是应用程序,可以理解为使用DTP的程序

RM(Resource Manager):资源管理器,这里可以理解为一个DBMS系统,或者消息服务器管理系统,应用程序通过资源管理器对资源进行控制。资源必须实现XA定义的接口

TM(Transaction Manager):事务管理器,负责协调和管理事务,提供给AP应用程序编程接口以及管理资源管理器

XA:XA 协议描述了 TM 与 RM 之间的接口,允许多个资源在同一分布式事务中访问。XA 协议使用 2PC(Two Phase
Commit,两阶段提交)原子提交协议来保证分布式事务原子性。两阶段提交是指将提交过程分为两个阶段,即准备阶段(投票阶段)和提交阶段(执行阶段)

xa引入第三方的一个角色来监控这两者的状态,根据这个状态进行调整。

2pc

在保证数据的一致性原子性,使用了一种算法,名字就叫做2pc。

首先发起一个prepare的询问,是否可以执行事务提交,可以的话给一个响应ok的指令,

各个管理器进行事务操作,会把事务日志做一个记录,因为事务支持回滚。

事务执行完的结果返回给tm 只有两种结果,成功和失败,如果有一个失败,那么就是失败,这是为了保证数据的一致性。 最后再根据返回的指令完成提交还是回滚。

所谓二阶段提交就是 第一步prepare询问,如果返回都是ok那么执行第二第二步提交或者回滚。

第一阶段:

事务询问

1 向所有的ap发送事务内容是否可以执行事务提交操作。

2 执行事务操作,写入事务日志

3 向每个ap反馈事务访问的响应

第二阶段

1 成功 tm向ap发送commit 请求,ap然后向tm返回操作结果

2 失败 事务回滚,不论成功还是失败的各个rm 都回滚 ,根据日志进行回滚,并且把事务结果的返回tm,并且结束

2pc优点和缺点

1、同步阻塞问题。
二级段提交的执行过程中,所有参与该事务操作的逻辑的都在阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他的任务操作
2、单点故障。
协调者的角色在整个二级段提交协议中起到了非常重要的作用,一旦协调者出现问题,那么整个第二阶段提交流程将无法运转,更为严重的是,协调者在阶段二中出现问题的话,那么其他的参与者将会处于锁定事务资源的状态中,而无法继续完成事务操作。
3.数据不一致
在二阶段提交的阶段二中,即提交事务提交的时候,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
4、太过保守
如果在协调者指示参与者进行事务提交询问的过程中,参与者出现故障而导致协调者始终无法获取到所有参与者的响应的消息的话,这时协调者只能依靠其自身的超时机制来判断是否中断事务,这样的策略比较保守,换句话说,二阶段提交协议没有设计相应的容错机制,当任意一个参与者节点宕机,那么协调者超时没收到响应,就会导致整个事务回滚失败。

3pc提交

多了一个cancommit 去询问是否可以提交事务 cancommit precommit docommit

分布式事务解决方案

若一致性 碱性

强一致性 酸性

幂等 : 在一个订单内消息发送了两次产生的重复次数就是幂等问题。

1 采用数据库的唯一约束问题,不可以有重复出现,唯一约束报错后通过捕捉错误,

2 token机制,token 生成唯一的一个token 把token 传入服务端 把token设置唯一约束。

状态机

根据状态机去判断对象处于什么状态然后进行什么操作。表示一个对象在生命周期里经历的状态 ,状态机就是根据一个不同的状态进行一个不同的响应。

1 实现幂等就是通过 where status =1 属于支付中,where status =2

2 通过状态来进行业务驱动流程的变化。

通过mq 解决数据一致性问题

通过消息队列解决

错误补偿重试 消息没有签收 就进行重试,注意一个幂等一个消息的是否签收 。

消息队列的顺序性,通过时间戳 ,把时间戳放入redis中,然后在消费端在取出来。

互联网企业一般采用弱一致性也就是最终一致性的原则。通过mq进行消息队列的存储和消费。

tcc事务补偿机制

TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:

  • Try 阶段主要是对业务系统做检测及资源预留
  • Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
  • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

举个例子,假入 Bob 要向 Smith 转账,思路大概是: 我们有一个本地方法,里面依次调用

  1. 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
  2. 在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
  3. 如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些

缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

posted on 2020-04-19 21:28  全国学渣代表  阅读(171)  评论(0编辑  收藏  举报