在单体架构中,我们使用关系型数据库的ACID特性,可以实现事务机制,但在微服务架构中,一次业务操作可能跨越多个服务,需要操作多个数据库,此时一个服务失败只有失败的业务会回滚,其他服务却成功了,导致数据不一致。

四种事务模式


AT

AT是一种保证最终一致性的两阶段提交模式,克服了XA模式长时间锁定资源的缺点。
第一阶段(本地提交):

  1. 拦截业务SQL、提取表名、条件。
  2. 查询并保存更新前的数据快照。
  3. 执行业务SQL。
  4. 查询并保存更新后的数据。
  5. 将执行SQL前后数据快照和SQL信息写入UNDO_LOG表。
  6. 向TC申请全局锁。
  7. 提交本地数据库事务,释放本地锁。
    第二阶段:
  • 成功:TC通知各RM异步删除undo_log,释放全局锁。
  • 失败:TC通知RM回滚,RM先检查当前数据是否等于写后快照(防脏写),如果相等则根据写前快照生成反向SQL执行补偿,最后删除undo_log,释放全局锁。
    优点:
  • 代码侵入性低:只需要加一个注解(如 @GlobalTransactional)。
  • 性能好:一阶段就提交并释放了本地锁。
    缺点:
  • 依赖关系型数据库:需要支持SQL。
  • 全局锁竞争:高并发写同一行会导致性能下降。
  • 脏写问题:如果有非Seata代理的业务在事务期间执行了写操作,回滚会失败。

TCC

Saga

XA(2PC)

XA是强一致性的两阶段提交方案。
第一阶段(准备):
事务协调者向所有数据源发送准备请求,各数据库执行业务SQL,但不提交事务,仍然持有数据库本地锁。
第二阶段(提交/回滚):

  • 如果所有数据库操作都成功,事务协调者发送提交指令,所有数据库都进行提交并释放锁。
  • 只要有一个数据库失败或超时,事务协调者发送回滚指令,所有数据库回滚并释放锁。
    优点:
  • 无侵入:常用数据库都支持
  • 强一致性:
    缺点:
  • 性能极差:整个事务期间数据库都被锁定。

实现


Seata

见快速开始

核心架构

  1. 事务协调者TC (Transaction Coordinator):
    • Seata的服务端,负责维护全局事务和分支事务的状态,驱动全局事务的提交或回滚。
  2. 事务管理器TM (Transaction Manager):
    • 嵌入在发起全局事务的业务代码中(如带@GlobalTransactional注解的方法)
    • 负责开启全局事务,提交或回滚事务。
  3. 资源管理器RM (Resource Manager):
    • 管理分支事务处理的资源,负责向TC注册分支事务、报告分支状态,并接收TC指令执行分支提交或回滚。