1、分布式事务判断标准

多服务多数据源
关于增删改的远程调用

2、分布式事务与分布式锁?

分布式事务:某个事务失败的话,需要回滚当前事务,数据保证一致
分布式锁:解决的是多并发情况下对共享数据操作的时候,防止数据错乱

3、分布式事务原理

image.png

  1. TC事务协调者——启动注册seata服务
  2. TM事务管理器——开启全局事务,并携带全局事务ID(XID);提交/回滚事务,定义事务的范围
  3. 全局事务保存到数据库三张表
  4. 远程调用传递XID给服务提供方(RM)
  5. 把分支事务注册到TC,并携带XID
  6. 接收到分支事务的注册,保存到分支表中(全局事务ID字段,一对多==>规定在同一事务中)
  7. TM向TC发送成功执行的通知commit
  8. TC接收到TM和RM所有的提交信息,决策是否提交/回滚
  9. 若有一个失败的,TC通知TM回滚==>TM执行回滚==>RM回滚(实际)

    4、分布式事务XID传递原理

    将XID存放在请求头中,底层是基于SpringMVC的拦截器HandlerInterceptor,拦截将值存放在TreadLocal中,传递给其他服务

    5、Seata执行原理(AT模式)

    5.1第一阶段-事务收集

    image.png
    本地事务提交之前,各分支事务都要在TC(全局事务调解者)注册BranchId,利用SELECT FOR UPDATE语句为要修改的数据进行申请全局锁,如果一直拿不到锁,则需要回滚本地事务。

    5.2第二阶段-事务决议

    提交:
    image.png
    回滚:
    image.png

    6、项目集成seata

    i)引入依赖
  • 依赖seata-spring-boot-starter,支持yml配置
  • 依赖spring-cloud-starter-alibaba-seata,内部集成了seata,并实现了xid传递

i i)配置类

  1. /**
  2. * @ClassName SeataWebMvcConfig.java
  3. * @Description webMvc高级配置
  4. */
  5. @Configuration
  6. public class SeataWebMvcConfig extends WebMvcConfig {
  7. /***
  8. * @description 解决XID传递问题
  9. * @return
  10. * @return: com.alibaba.cloud.seata.web.SeataHandlerInterceptor
  11. */
  12. @Bean
  13. public SeataHandlerInterceptor seataHandlerInterceptor(){
  14. return new SeataHandlerInterceptor();
  15. }
  16. /**
  17. * @Description 拦截器
  18. */
  19. @Override
  20. public void addInterceptors(InterceptorRegistry registry) {
  21. super.addInterceptors(registry);
  22. registry.addInterceptor(seataHandlerInterceptor()).addPathPatterns("/**");
  23. }
  24. }

iii)配置文件(每个RM)
day08-分布式事务(Seata) - 图5
@GloalTransactional(每个RM)
image.png

4、我们项目中哪些功能存在分布式事务问题?
增删除改查
添加购物车:
下单的时候:
删除redis的购物车中的数据,也要通过

你们项目中那些地方设计到分布式事务的问题?(用户 品牌 菜品 等
1、讲问题背景(项目调用链路)
2、解决方案
配置seata
3、原理是什么
集成seata后,由seata对数据源对象进行管理,对数据源进行代理,提取sql中的元数据(表,字段,值,类型)并执行,将内容保存到数据库下的undo_logo表中,分为前置镜像和后置镜像,TC协调决策是否回滚还是提交;
提交:都成功==>删除undo_logo表
失败:有一个执行失败,对比前后镜像数据,反向解析出sql,还原数据
4、需要注意什么
seata无法避免脏写,在并发的情况下,镜像数据被改变无法还原,会不断重试
需要我们在业务层面判断,处理,避免这种情况的发生