分布式事务的解决方式

mysql的三种日志

1、undo log
为了满足事务的原子性,在操作任何数据之前,首先将数据备份到Undo Log。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。
2、redo log
只是记录了数据发生了那些修改的日志,并且是物理的修改,事务提交之前,会把修改的内容写入到redo log中,如事务提交之后,某页发生了什么内容的修改,当提交的时候,就可以直接持久化redo 日志当中的内容,从而可以减少io。

3、bin log日志
它会把所有sql的执行过程都保存在该日志当中,
主从复制 ,主主复制就是通过bin log日志 实现。

分布式事务的解决方式

一、事后对账

在这里插入图片描述
比如,上图一个扣库存的服务,另一个扣钱的服务,在事后发现只有一个扣成功,那么就代表该订单的事务是失败的,所以其中成功的那个也应该回滚。
在这里插入图片描述

二、rabbitmq中间件

在这里插入图片描述

如主控服务 订单作为生产者服务A 执行完成事务 并且完成事务的提交,之后, 发出消息 给到rabbitmq ,让其他服务可以进行消费动作,如扣款服务,那可以通过到mq当中接收消息来消费。业务失败,可以通过 消费端开启手动确认消费,业务失败则消息重回队列的方式来保证 最终一致。
在这里插入图片描述
保证消息的可靠性,可以增加数据库,将发送消息的指令保存到数据库当中,这样多了一个保险,就是在消费者消费完成之后,再去数据库中,对该条信息完成 最终的消费的状态修改,能够协同两个服务A和B

不是强一致,但是是最终一致的。

三、二阶段提交

>代码如下(示例):
在这里插入图片描述
如上图,第一个阶段 所有的微服务完成自己的事务,但是不提交,并且把自己事务是否成功的消息告诉协调者,协调者来在第二个阶段决定事务是否提交。
缺点:当第二个阶段执行的服务挂掉,那么服务则无法继续执行提交或者回滚的操作
因为第一个阶段的操作需要等待第二个阶段的响应才能完成,在此期间,会保持资源锁定,其他线程不可获取,导致性能受影响。

TCC try confirm cancel

2pc 就是指上面刚说到的二阶段提交的方式,也就是在二阶段提交的方式上面做了优化。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图是关于 TCC的实例,是一个 服务从A账户完成扣款,然后另一个服务扣库存。这里只拿扣款服务举例,扣库存的服务类似。
第一阶段:需要把A账户进行扣款,需要做的是,在账户表增加一个冻结部分的字段,将其设置为30,然后该服务就可以完成提交了。
第二阶段,
如果第一阶段的所有服务的事务,都执行成功,那么需要提交,就是把余额扣除30,并且把冻结部分的钱置为0。
如果第一阶段的服务有事务失败了,那么就只需要把冻结部分的前置为0即可。

优点:解决了 二阶段提交,资源锁的占用问题,所有阶段都是独立的事务,互不影响。
缺点:每一个微服务 都需要写 try confirm cancel 的代码,代码侵入严重。

seata

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
seata 也是两个阶段,并且两个阶段也是独立的,第一个阶段执行完毕之后就直接提交了,然后向TC发送自己的执行状态。
在这里插入图片描述

第一个阶段虽然是完成了提交,但是会把事务执行之前的数据状态写在undo log 中,会把数据的修改状态写在redo log中。

二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。

二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据(也就是利用undo log 回滚);但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。

优点:
相较与二阶段提交,seata 每个事务都是单独提交的,事务执行完就在本地提交了,不需要等待和资源锁定。
相较于TCC的方式,seata 二阶段的提交和回滚事务,都是由框架完成的,通过类似于undo log 和redo log 完成事务的提交和回滚的操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值