在微服务项目中 有A、B、C三个服务 其中 A调用B服务 ,B调用C, 这些就是跨服务调用了,在A服务中 还调用了一个当前模块执行插入数据的方法(在这里我就叫它为AA 也就是mybatis/spring管理的本地事务)
A服务开启全局事务注解 @GlobalTransactional
B服务注解 @Transactional(propagation = Propagation.REQUIRES_NEW)
C服务注解 @Transactional(propagation = Propagation.REQUIRES_NEW)
AA是所属A模块中的Service的一个方法 也叫本地服务
/**
* 如果开启分布式事务,就设置response.status = 500,seata的tm(事务管理器)
* 并主动回滚
*
*/
private static void setRespErrStatus(HttpServletResponse response) {
//如果开启分布式事务,设置错误状态码,让事务回滚
if (StringUtils.isNotBlank(RootContext.getXID())) {
log.error("全局捕异常 捕获到Seata " + " 事务id-------------API--------->" + RootContext.getXID());
log.error("全局捕异常 捕捉到Seata 事务" + RootContext.getXID() + " 抛出异常 设置response 状态码为 500 ");
log.error("全局捕获到 Seata异常 全局回滚");
try {
response.setStatus(500);
GlobalTransactionContext.reload(RootContext.getXID()).rollback();
log.error(" 数据提交失败");
} catch (TransactionException e) {
log.error(" 捕获seata异常·不处理");
}
} else {
response.setStatus(200);
}
}
在Feign调用前 判断 xid是否为空 如果不为空则将 xid绑定
String xid =RootContext.getXID() ; //获取 xid
RootContext.bind(xid); //绑定 xid
原因 : 这个是因为分布式事务调用是正常的,只是本地事务失败了 所有分布式事务都提交了,本地事务未提交 ()
String xid =RootContext.getXID() ;
xxService.insertScoresGoodInfos(sSysProjectMenu.getPath(),xid);
@Override
public int insertScoresGoodInfos(String sysType ,String xid) {
RootContext.bind(xid); // 将本地事务加到分布式事务组中去
return baseMapper.insertScoresGoodInfos(sysType, sysType + UUID.randomUUID().toString());
}
<spring-cloud.version>2021.0.8</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
<spring-boot.version>2.7.13</spring-boot.version>
<druid.version>1.2.18</druid.version>
<dynamic-ds.version>3.5.2</dynamic-ds.version>
<mysql.version>5.1.49</mysql.version>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Dynamic DataSource -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- Seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>