1、分布式事务判断标准
2、分布式事务与分布式锁?
分布式事务:某个事务失败的话,需要回滚当前事务,数据保证一致
分布式锁:解决的是多并发情况下对共享数据操作的时候,防止数据错乱
3、分布式事务原理
- TC事务协调者——启动注册seata服务
- TM事务管理器——开启全局事务,并携带全局事务ID(XID);提交/回滚事务,定义事务的范围
- 全局事务保存到数据库三张表
- 远程调用传递XID给服务提供方(RM)
- 把分支事务注册到TC,并携带XID
- 接收到分支事务的注册,保存到分支表中(全局事务ID字段,一对多==>规定在同一事务中)
- TM向TC发送成功执行的通知commit
- TC接收到TM和RM所有的提交信息,决策是否提交/回滚
- 若有一个失败的,TC通知TM回滚==>TM执行回滚==>RM回滚(实际)
4、分布式事务XID传递原理
将XID存放在请求头中,底层是基于SpringMVC的拦截器HandlerInterceptor,拦截将值存放在TreadLocal中,传递给其他服务5、Seata执行原理(AT模式)
5.1第一阶段-事务收集
本地事务提交之前,各分支事务都要在TC(全局事务调解者)注册BranchId,利用SELECT FOR UPDATE语句为要修改的数据进行申请全局锁,如果一直拿不到锁,则需要回滚本地事务。5.2第二阶段-事务决议
提交:
回滚:
6、项目集成seata
i)引入依赖
- 依赖seata-spring-boot-starter,支持yml配置
- 依赖spring-cloud-starter-alibaba-seata,内部集成了seata,并实现了xid传递
i i)配置类
/**
* @ClassName SeataWebMvcConfig.java
* @Description webMvc高级配置
*/
@Configuration
public class SeataWebMvcConfig extends WebMvcConfig {
/***
* @description 解决XID传递问题
* @return
* @return: com.alibaba.cloud.seata.web.SeataHandlerInterceptor
*/
@Bean
public SeataHandlerInterceptor seataHandlerInterceptor(){
return new SeataHandlerInterceptor();
}
/**
* @Description 拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(seataHandlerInterceptor()).addPathPatterns("/**");
}
}
iii)配置文件(每个RM)
@GloalTransactional(每个RM)
4、我们项目中哪些功能存在分布式事务问题?
增删除改查
添加购物车:
下单的时候:
删除redis的购物车中的数据,也要通过
你们项目中那些地方设计到分布式事务的问题?(用户 品牌 菜品 等)
1、讲问题背景(项目调用链路)
2、解决方案
配置seata
3、原理是什么
集成seata后,由seata对数据源对象进行管理,对数据源进行代理,提取sql中的元数据(表,字段,值,类型)并执行,将内容保存到数据库下的undo_logo表中,分为前置镜像和后置镜像,TC协调决策是否回滚还是提交;
提交:都成功==>删除undo_logo表
失败:有一个执行失败,对比前后镜像数据,反向解析出sql,还原数据
4、需要注意什么
seata无法避免脏写,在并发的情况下,镜像数据被改变无法还原,会不断重试
需要我们在业务层面判断,处理,避免这种情况的发生