common-seata 分布式事务使用

分布式事务示意图

什么是分布式事务

上图所示,当请求 A 模块时:

  • A 模块 Mapper 直接操作 DB 得到数据集
  • 使用 Feign 调用 B 模块
  • B 模块 Mapper 操作 DB 得到数据集
  • 合并两步操作或者其他的操作

分析上图可能发生异常及其回滚:

  • 步骤 1 发生异常,Spring 事务会自动回滚
  • 步骤 2 发生异常,Spring 事务会自动回滚
  • 步骤 3 发生异常,3 会自动回滚,2 根据返回码抛出自定义异常 1 会自动回滚
  • 步骤 4 发生异常,Spring 事务会自动回滚 1 的操作,但是 3 的操作不会回滚
分布式事务目标

当 A 模块开启事务时,如果步骤 4 操作过程异常,步骤 3 的操作应该回滚

Seata 架构图

运行 Seata Server 服务端

docker run --name seata-server -p 8091:8091 -p 7091:7091 registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/seata-server:2.0.0

微服务客户端接入

添加依赖

依赖范围

服务提供方、调用方都需要添加此依赖

<dependency>
    <groupId>com.pig4cloud</groupId>
    <artifactId>pigx-common-seata</artifactId>
</dependency>

服务调用方声明 GlobalTransactional

@GlobalTransactional // 分布式事务注解
@Transactional(rollbackFor = Exception.class) // Spring 事务注解
public R consumer() {
    feign.providerMethod();  // 通过 Feign 调用服务提供方的接口
}
事务注解要求

服务提供方、调用方都需要添加 @Transactional Spring 事务注解

微服务涉及数据库添加 undo_log 表

表结构范围

服务提供方、调用方都需要添加此表

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;