基础概念
事务
是一个完整的逻辑处理工作单元
ACID
Atomaticity:原子性
Consistency:一致性
Isolation:隔离性
Durability:持久性
(日志先行)
-
Begin Transsion
-
执行业务逻辑
-
Commit/Rollback
分布式服务
涉及到多个服务、数据库的事务
其实就是将对同一数据库事务的概念扩大到了对多个数据库的事务
目的是为了保证分布式系统中的数据一致性
XA规范
AP,TM,RM之间都有一些交互
XA规范一句话概况:事务协调者用与数据库的接口来通知数据库事务的开始、结束以及提交、回滚等。XA接口函数是由数据库厂商来提供的
解决方案思路分析
事情做了无法后悔
往回去调太麻烦了,不去做
怎么让事情做了可以后悔
-
进行彩排,进行模拟
-
关键是必须有一种可以知道事务在任何地方所做的所有动作
-
提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)
三阶段基本没有人用
XA解决方案
2pc提交协议
XA方案包括2pc,3pc
两阶段完成分布式事务提交
就像是西式婚礼
如果都收到yes,就会进入第二个阶段,彻底提交
步骤
第一阶段:就是一个预提交阶段,投票阶段
第二阶段:回滚阶段,提交阶段。提交后就会释放占有的数据库连接的资源
当有一个参与的响应失败时,建议都回滚,比较靠谱
缺点
单点故障:协调者出错,事务会失败
阻塞资源:占用数据库连接,性能较低
数据不一致:二阶段出错,数据不一致(网络出错,断了,有些执行完有些没执行完)
如何解决
阻塞资源
不占用连接是否完成这个工作(提交、回滚)
前面执行完直接提交,协调者发提交动作就什么都不用做了
只需要记录数据原来的问题
回滚,需要知道原来数据的状态是怎么样的,要记下来,再下发命令的时候只需要重新回到原状态就行,提交的时候只需要把原状态删掉就行(seata对两阶段的优化)
数据不一致问题
利用脚本,检查数据,发现这种异常,原来A->B,1->2,现在B对应的1了,就会进行回滚或者前滚,让1变成2或者让B变成A
3pc提交协议
can commit
pre commit
do commit
相比于2pc的改进
节约了数据库连接的资源
如果第一次有NO,就浪费了一次数据库连接的资源,造成性能低下。所以在can commit先让他盘算一下,此时并不占用数据库连接,也不执行sql的语句
can commit:有参与者返回NO,协调者等待超时(这个阶段不存在超时),参与者没收到协调者的指令
各阶段超时怎么办:pre commit直接回滚,do commit自己进行提交(第三步大概率是进行提交的,只是概率问题)
tcc解决方案
是2pc的一个变种
2PC是在数据库层面解决数据库之间的分布式事务,TCC是在应用层解决分布式事务
Try Confirm Cancel
应用场景
一个方法中有Redis、Mysql执行update语句,执行出错了如何去回滚
阶段1:准备阶段
调用两个服务的try接口
这个阶段保证了扣钱可扣,价钱可加
阶段2:提交阶段
如果两个try接口都返回了yes,就调用confirm
有返回no或者超时的就返回cancel
案例
张三给李四转100
Try阶段:张三余额-100,张三冻结字段+100。李四冻结字段+100。(就是先尝试一下,可以就行,不行就算了)
Confirm阶段:张三冻结字段-100,李四冻结字段-100,余额+100
Cancel阶段:张三余额+100,冻结字段-100,李四冻结字段-100
AT解决方案
自动事务(Auto Transaction)
代码无侵入性
一阶段
-
拦截,解析SQL,备份数据,加载到undo_log表中
-
执行业务SQL,undo_log日志也会同步更新
二阶段
没有报错就删除undo_log以及锁的数据
报错就根据undo_log来回退数据
XA规范
AP,TM,RM之间都有一些交互
XA规范一句话概况:事务协调者用与数据库的接口来通知数据库事务的开始、结束以及提交、回滚等。XA接口函数是由数据库厂商来提供的
事件表解决方案
把一个大的事务拆成多个小的事务
通过一张事务表来解决
保证每个事务都是完整的,那么整个事务就是完整的
好处是降低了用户的响应时间
最大努力通知方案
第三方平台调用一定次数就不调用了
回调给我方支付系统
第三方的系统无法左右,第一次没收到没关系,第三方多发几次到我方支付系统那么也放弃了
让我方支付系统主动去查
重复通知机制
消息校对机制:通知多次还没收到,可以主动去查有没有记录