【IT老齐019】Seata分布式事务解决方案

发布时间 2023-05-05 21:59:04作者: Faetbwac

【IT老齐019】Seata分布式事务解决方案

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前,其内部版本在阿里系内部一直扮演着应用架构层数据一致性的中间件角色,帮助经济体平稳的度过历年的双11,对上层业务进行了有力的技术支撑。经过多年沉淀与积累,其商业化产品先后在阿里云、金融云上售卖。2019.1 为了打造更加完善的技术生态和普惠技术成果,Seata 正式宣布对外开源,未来 Seata 将以社区共建的形式帮助用户快速落地分布式事务解决方案。

常见场景

1683272155975

通用解决方案

二阶段提交

1683272477692

1683272618465

Seata

三个角色

  • 事务管理器(TM):决定什么时候全局提交/回滚(司令官)
  • 事务协调者(TC):负责通知命令的中间件Seata-Server(传令官)
  • 资源管理器(RM):做具体事儿的工具人(大头兵)

工作机制

1683273271625

1683273378468

注意,RM本地执行完成会直接提交事务

1683273572644

1683273613726

AT模式下实现数据自动提交、回滚

分布式服务中数据库维护一个UODO_LOG的数据表存储反向SQL,分布式事务成功则删出uodo_log;分布式事务失败则执行uodo_log,反向SQL的生成方式借助SQL Parser

1683274575010

并发场景下解决脏读和脏写

回顾脏写、脏读、不可重复读、幻读

  • 脏写
    • 并发事务下,由于两个事务同时修改一个数据,之后先执行的事务(未提交)进行回滚,导致后发事务数据丢失,对于后发事务来说,发生了脏写
  • 脏读
    • 并发事务下,事务 B 去查询了事务 A 修改过的数据,但是此时事务 A 还没提交,所以事务 A 随时会回滚导致事务 B 再次查询就读不到刚才事务 A 修改的数据了,对于B事务来说,发生了脏读
  • 使用TC自带的分布式锁解决脏写

    • @GlobalTransactional
  • 通过 SELECT FOR UPDATE 语句的代理解决脏读

    • @GlobalTransactional+SELECT FOR UPDATE
    • @GlobalLock+@Transactional+SELECT FOR UPDATE(无分布式事务需求可使用)
  • 特点

    • 一阶段本地事务提交前,需要确保先拿到 全局锁
    • 拿不到 全局锁 ,不能提交本地事务。
    • 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

1683279495390

  • 后发事务由于无法获得全局锁,被迫回滚本地事务释放本地锁,避免脏写

1683279598780

1683280041912