分布式事务
使用场景 同一个事务对两个数据库操作,事务肯定是会失效的 因为一个事务就是一个数据库连接,不同的连接就是不同的事务
Seata 是什么?
Seata是一款分布式事务解决方案,用AT模式是阿里推荐的
事务模式:TCC、SAGA、XA
常见分布式事务解决方案
1、seata 阿里分布式框架
2、消息队列
3、saga
4、XA
这四种都是 两阶段(2PC)的协议:完成整个分布式事务需要两个步骤完成
2PC 协议?
预处理Prepare
参与方 数据库或应用
提交Commit
处理流程:一、预处理
询问:协调者向各个参与者 发起询问 是否可以执行事务操作,然后等待各个事务响应
执行:各个参与者收到协调者的事务请求后,执行事务操作,并将undo、redo信息 记录在事务日志表中
预处理sql执行任务是否满足条件(为什么这样设计:1、提交的话 对数据覆盖)
响应:如果参与者成功执行了事务并写入Undo、Redo信息,则向协调者返回yes响应,当然参与者也可能宕机 不响应。如果响应为No,则协调者触发回滚
二、提交/回滚机制
commit通知:请求协调者向所有参与者发送了Commit请求
事务提交: 参与者收到commit请求后,执行事务提交、提交完成后释放事务执行期间占用的所有资源
反馈结果:参与者执行事务提交后向协调者发送Ask响应(没用100%的成功率)
完成事务:接收到所有参与者的Ack响应后,完成事务提交
2PC的问题
1、参与者在等待协调者发送指令时 其实是在等待其他参与者的响应。在此过程中其参与者是不能做其他操作的 也就是阻塞了
2、协调者可能会挂掉
3、数据不一致:如果参与者之一宕机,则无法向协调者发送消息 就无法判断事务成功失败
AT协议(Auto Transaction)
AT模式是一种无侵入的分布式事务解决方案、我们只需要编业务SQL就行
一阶段:
Setta会拦截"业务SQL",提取元数据,在数据被更新前,update user set name ="李五" where name ="李四"
将其保存为befor image(select * from user where nbame ='李四'。
再业务数据更新之后,再将其保存为"after image" 最后生成行锁。以上操作全部在一个数据库内完成,保证操作的原子性
二阶段:提交
提交的话 因为业务sql在阶段一已经提交至数据库,所以seata框架只需要将保存的快照数据和行锁删掉完成数据清理就行了
回滚:
数据校验:after image 和数据库对比(防止脏数据)
还原数据:before image -> 逆向SQL ->数据还原
删除中间数据:见提交