irpas技术客

【Spring Cloud Alibaba】Seata 分布式事务_Tellsea

大大的周 3090

文章目录 【Spring Cloud Alibaba】Seata 分布式事务1、Spring Cloud Alibaba Seata2、服务公共内容(1)相关依赖(2)application.yml(3)file.conf、registry.conf(4)AjaxResult(5)代码生成(6)创建模块数据库 3、搭建账户服务4、搭建订单服务5、搭建库存服务6、测试下单业务(1)检查服务启动结果(2)正常情况下单(3)出错情况下单(4)增加 Seata 事物 7、常见报错(1)endpoint format should like ip:port 微信公众号

【Spring Cloud Alibaba】Seata 分布式事务 1、Spring Cloud Alibaba Seata

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

Seata 的官网,https://seata.io/zh-cn/ Spring Cloud 快速集成 Seata,https://github.com/seata/seata-samples/blob/master/doc/quick-integration-with-spring-cloud.md

本篇文章使用的是 Seata 的 AT 模式 业务需求:下订单 -> 减库存 -> 扣余额 -> 改订单状态

源码中的模块名称变更了,之前大意多了一个 boot,这里修改了一下

变更前变更后spring-cloud-alibaba-boot-seata-accountspring-cloud-alibaba-seata-accountspring-cloud-alibaba-boot-seata-orderspring-cloud-alibaba-seata-orderspring-cloud-alibaba-boot-seata-storagespring-cloud-alibaba-seata-storage
2、服务公共内容

公共内容需要在每个模块中都添加,除了 application.yml 有一点区别,其他所有配置相同

(1)相关依赖

三个模块的依赖相同

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>${spring-cloud-starter-openfeign.version}</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus-boot-starter.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>com.spring4all</groupId> <artifactId>swagger-spring-boot-starter</artifactId> <version>${swagger-spring-boot-starter.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> (2)application.yml

三个服务需要分别修改端口,数据库名字,其他的 application.yml 配置文件都一样

模块端口端点数据库spring-cloud-alibaba-boot-seata-account80079007alibaba-seata-accountspring-cloud-alibaba-boot-seata-order80089008alibaba-seata-orderspring-cloud-alibaba-boot-seata-storage80099009alibaba-seata-storage
# 应用配置 server: port: 8007 # 端点监控 management: endpoint: health: show-details: always endpoints: jmx: exposure: include: '*' web: exposure: include: '*' server: port: 9007 spring: # 应用名称 application: name: spring-cloud-alibaba-boot-seata-account datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/alibaba-seata-account?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 serialization: write-dates-as-timestamps: false # 微服务配置 cloud: # Nacos配置 nacos: discovery: namespace: sandbox-configuration password: nacos server-addr: localhost:8848 username: nacos alibaba: # Seata配置 seata: tx-service-group: tellsea_tx_group # MybatisPlus配置 mybatis-plus: configuration: map-underscore-to-camel-case: true auto-mapping-behavior: full log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath*:mapper/**/*Mapper.xml (3)file.conf、registry.conf

在你下载的 seata 的 bin,目录中复制到项目的 resource 目录下 并在 file.conf 文件中增加,与 store 同级,因为默认配置文件中没有

service { #vgroup->rgroup vgroupMapping.tellsea_tx_group = "default" #only support single node default.grouplist = "127.0.0.1:8091" #degrade current not support enableDegrade = false #disable disable = false #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent max.commit.retry.timeout = "-1" max.rollback.retry.timeout = "-1" } (4)AjaxResult

三个服务的 AjaxResult 相同

package cn.tellsea.entity; import org.springframework.http.HttpStatus; import org.springframework.util.ObjectUtils; import java.util.HashMap; /** * 公共返回值 * * @author Tellsea * @date 2021/12/31 */ public class AjaxResult<T> extends HashMap<String, Object> { /** * 状态码 */ public static final String CODE_TAG = "code"; /** * 返回内容 */ public static final String MSG_TAG = "msg"; /** * 数据对象 */ public static final String DATA_TAG = "data"; private static final long serialVersionUID = 1L; /** * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 */ public AjaxResult() { } /** * 初始化一个新创建的 AjaxResult 对象 * * @param code 状态码 * @param msg 返回内容 */ public AjaxResult(int code, String msg) { super.put(CODE_TAG, code); super.put(MSG_TAG, msg); } /** * 初始化一个新创建的 AjaxResult 对象 * * @param code 状态码 * @param msg 返回内容 * @param data 数据对象 */ public AjaxResult(int code, String msg, T data) { super.put(CODE_TAG, code); super.put(MSG_TAG, msg); if (!ObjectUtils.isEmpty(data)) { super.put(DATA_TAG, data); } } /** * 返回成功消息 * * @return 成功消息 */ public static AjaxResult<Void> success() { return AjaxResult.success("操作成功"); } /** * 返回成功数据 * * @return 成功消息 */ public static <T> AjaxResult<T> success(T data) { return AjaxResult.success("操作成功", data); } /** * 返回成功消息 * * @param msg 返回内容 * @return 成功消息 */ public static AjaxResult<Void> success(String msg) { return AjaxResult.success(msg, null); } /** * 返回成功消息 * * @param msg 返回内容 * @param data 数据对象 * @return 成功消息 */ public static <T> AjaxResult<T> success(String msg, T data) { return new AjaxResult(HttpStatus.OK.value(), msg, data); } /** * 返回错误消息 * * @return */ public static AjaxResult<Void> error() { return AjaxResult.error("操作失败"); } /** * 返回错误消息 * * @param msg 返回内容 * @return 警告消息 */ public static AjaxResult<Void> error(String msg) { return AjaxResult.error(msg, null); } /** * 返回错误消息 * * @param msg 返回内容 * @param data 数据对象 * @return 警告消息 */ public static <T> AjaxResult<T> error(String msg, T data) { return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data); } /** * 返回错误消息 * * @param code 状态码 * @param msg 返回内容 * @return 警告消息 */ public static AjaxResult<Void> error(int code, String msg) { return new AjaxResult(code, msg, null); } public Integer getCode() { return (Integer) super.get(CODE_TAG); } public String getMsg() { return (String) super.get(MSG_TAG); } public T getData() { return (T) super.get(DATA_TAG); } } (5)代码生成

使用代码生成器,分别生成 controller、service、serviceImpl、mapper、mapper.xml 文件,不会使用的看上一篇文章

【Spring Cloud Alibaba】Mybatis Plus 代码生成器:https://mp.weixin.qq.com/s/9OZRbIqhLEOhH3QKEJWwPg

有不懂的地方,可以微信公众号留言,项目源码在:https://gitee.com/tellsea/spring-cloud-alibaba-learn

(6)创建模块数据库

3、搭建账户服务

创建 spring-cloud-alibaba-boot-seata-account 模块,先把第二节的账户服务都操作完成

控制层

package cn.tellsea.controller; import cn.tellsea.entity.AjaxResult; import cn.tellsea.service.IBizAccountService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; /** * <p> * 账户表 前端控制器 * </p> * * @author Tellsea * @since 2021-12-31 */ @RestController @RequestMapping("/bizAccount") public class BizAccountController { @Autowired private IBizAccountService accountService; @ApiOperation("扣减账户") @PostMapping("/account/decrease") AjaxResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money) { return accountService.decrease(userId, money); } }

接口层

package cn.tellsea.service; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizAccount; import com.baomidou.mybatisplus.extension.service.IService; import java.math.BigDecimal; /** * <p> * 账户表 服务类 * </p> * * @author Tellsea * @since 2021-12-31 */ public interface IBizAccountService extends IService<BizAccount> { /** * 扣减账户 * * @param userId * @param money * @return */ AjaxResult decrease(Long userId, BigDecimal money); }

接口实现层

package cn.tellsea.service.impl; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizAccount; import cn.tellsea.mapper.BizAccountMapper; import cn.tellsea.service.IBizAccountService; import cn.tellsea.utils.BigDecimalUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * <p> * 账户表 服务实现类 * </p> * * @author Tellsea * @since 2021-12-31 */ @Slf4j @Service public class BizAccountServiceImpl extends ServiceImpl<BizAccountMapper, BizAccount> implements IBizAccountService { @Override public AjaxResult decrease(Long userId, BigDecimal money) { log.info("------->扣减余额开始"); //模拟超时异常,全局事务回滚 //暂停几秒钟线程 //try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } BizAccount account = baseMapper.selectById(userId); account.setResidue(BigDecimalUtils.subtract(account.getResidue(), money)); account.setUsed(BigDecimalUtils.add(account.getUsed(), money)); baseMapper.updateById(account); log.info("------->扣减余额结束"); return AjaxResult.success("扣减余额成功"); } }

账户模块需要增加一个 BigDecimalUtils 工具类

package cn.tellsea.utils; import java.math.BigDecimal; import java.math.RoundingMode; /** * 金额计算工具类 * * @author Tellsea * @date 2021/12/31 */ public class BigDecimalUtils { /** * 默认保存2位小数点 */ private static int POINTS = 2; /** * 默认进位方式 */ private static RoundingMode MODE = RoundingMode.CEILING; /** * 加 * * @param a * @param b * @return */ public static BigDecimal add(BigDecimal a, BigDecimal b) { if (a == null) { a = BigDecimal.valueOf(0.00); } if (b == null) { b = BigDecimal.valueOf(0.00); } return computer(1, a, b, POINTS, MODE); } public static BigDecimal add(BigDecimal a, BigDecimal b, int points, RoundingMode mode) { if (a == null) { a = BigDecimal.valueOf(0.00); } if (b == null) { b = BigDecimal.valueOf(0.00); } return computer(1, a, b, points, mode); } /** * 减 * * @param a * @param b * @return */ public static BigDecimal subtract(BigDecimal a, BigDecimal b) { if (a == null) { a = BigDecimal.valueOf(0.00); } if (b == null) { b = BigDecimal.valueOf(0.00); } return computer(2, a, b, POINTS, MODE); } public static BigDecimal subtract(BigDecimal a, BigDecimal b, int points, RoundingMode mode) { if (a == null) { a = BigDecimal.valueOf(0.00); } if (b == null) { b = BigDecimal.valueOf(0.00); } return computer(2, a, b, points, mode); } /** * 乘 * * @param a * @param b * @return */ public static BigDecimal multiply(BigDecimal a, BigDecimal b) { return computer(3, a, b, POINTS, MODE); } /** * 除 * * @param a * @param b * @return */ public static BigDecimal divide(BigDecimal a, BigDecimal b) { if (b.compareTo(BigDecimal.ZERO) == 0) { return BigDecimal.valueOf(0.00); } return computer(4, a, b, POINTS, MODE); } public static BigDecimal divide(BigDecimal a, BigDecimal b, int points, RoundingMode mode) { return computer(4, a, b, points, mode); } /** * 计算方法 * * @param type 1-加 2-减 3-乘 4-除 * @param a * @param b * @param points * @param mode * @return */ public static BigDecimal computer(int type, BigDecimal a, BigDecimal b, int points, RoundingMode mode) { BigDecimal rs; switch (type) { case 1: rs = a.add(b).setScale(points, mode); break; case 2: rs = a.subtract(b).setScale(points, mode); break; case 3: rs = a.multiply(b).setScale(points, mode); break; default: rs = a.divide(b, points, mode); break; } return rs; } public BigDecimal multiply(BigDecimal a, BigDecimal b, int points, RoundingMode mode) { return computer(3, a, b, points, mode); } }

启动类增加注解

@EnableDiscoveryClient @EnableFeignClients @MapperScan("cn.tellsea.mapper") 4、搭建订单服务

创建 spring-cloud-alibaba-boot-seata-order 模块,先把第二节的账户服务都操作完成 控制层

package cn.tellsea.controller; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizOrder; import cn.tellsea.service.IBizOrderService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 订单表 前端控制器 * </p> * * @author Tellsea * @since 2021-12-31 */ @RestController @RequestMapping("/bizOrder") public class BizOrderController { @Autowired private IBizOrderService orderService; @ApiOperation("创建订单") @GetMapping("/createOrder") public AjaxResult createOrder(BizOrder entity) { return orderService.createOrder(entity); } }

接口层

package cn.tellsea.service; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizOrder; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * 订单表 服务类 * </p> * * @author Tellsea * @since 2021-12-31 */ public interface IBizOrderService extends IService<BizOrder> { /** * 创建订单 * * @param entity * @return */ AjaxResult createOrder(BizOrder entity); }

接口实现层

package cn.tellsea.service.impl; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizOrder; import cn.tellsea.feignclient.FeignBizAccountService; import cn.tellsea.feignclient.FeignBizStorageService; import cn.tellsea.mapper.BizOrderMapper; import cn.tellsea.service.IBizOrderService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * <p> * 订单表 服务实现类 * </p> * * @author Tellsea * @since 2021-12-31 */ @Slf4j @Service public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> implements IBizOrderService { @Autowired private FeignBizAccountService accountService; @Autowired private FeignBizStorageService storageService; @Override public AjaxResult createOrder(BizOrder entity) { log.info("------>开始新建订单"); baseMapper.insert(entity); log.info("------>订单微服务开始调用库存,扣减count"); storageService.decrease(entity.getProductId(), entity.getCount()); log.info("------>订单微服务开始调用库存,扣减end"); log.info("------>订单微服务开始调用账户,扣减money"); accountService.decrease(entity.getUserId(), entity.getMoney()); log.info("------>订单微服务开始调用账户,扣减end"); log.info("------>开始修改订单状态"); entity.setStatus(2); baseMapper.updateById(entity); log.info("------>修改订单状态完毕"); log.info("------>下单完毕"); return AjaxResult.success("下单成功"); } }

启动类增加注解

@EnableDiscoveryClient @EnableFeignClients @MapperScan("cn.tellsea.mapper")

增加账户服务远程调用接口

package cn.tellsea.feignclient; import cn.tellsea.entity.AjaxResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import java.math.BigDecimal; /** * 账户服务 * * @author Tellsea * @date 2021/12/31 */ @FeignClient("spring-cloud-alibaba-boot-seata-account") public interface FeignBizAccountService { /** * 扣减账户余额 * * @param userId * @param money * @return */ @PostMapping("/bizAccount/account/decrease") AjaxResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money); }

增加库存服务远程调用接口

package cn.tellsea.feignclient; import cn.tellsea.entity.AjaxResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; /** * 库存服务 * * @author Tellsea * @date 2021/12/31 */ @FeignClient(value = "spring-cloud-alibaba-boot-seata-storage") public interface FeignBizStorageService { /** * 扣减库存 * * @param productId * @param count * @return */ @PostMapping("/bizStorage/storage/decrease") AjaxResult decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count); } 5、搭建库存服务

创建 spring-cloud-alibaba-boot-seata-storage 模块,先把第二节的账户服务都操作完成 控制层

package cn.tellsea.controller; import cn.tellsea.entity.AjaxResult; import cn.tellsea.service.IBizStorageService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 库存表 前端控制器 * </p> * * @author Tellsea * @since 2021-12-31 */ @RestController @RequestMapping("/bizStorage") public class BizStorageController { @Autowired private IBizStorageService storageService; @ApiOperation("扣减库存") @RequestMapping("/storage/decrease") public AjaxResult decrease(Long productId, Integer count) { return storageService.decrease(productId, count); } }

接口层

package cn.tellsea.service; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizStorage; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * 库存表 服务类 * </p> * * @author Tellsea * @since 2021-12-31 */ public interface IBizStorageService extends IService<BizStorage> { /** * 扣减库存 * * @param productId * @param count * @return */ AjaxResult decrease(Long productId, Integer count); }

接口实现层

package cn.tellsea.service.impl; import cn.tellsea.entity.AjaxResult; import cn.tellsea.entity.BizStorage; import cn.tellsea.mapper.BizStorageMapper; import cn.tellsea.service.IBizStorageService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * <p> * 库存表 服务实现类 * </p> * * @author Tellsea * @since 2021-12-31 */ @Slf4j @Service public class BizStorageServiceImpl extends ServiceImpl<BizStorageMapper, BizStorage> implements IBizStorageService { @Override public AjaxResult decrease(Long productId, Integer count) { log.info("------->中扣减库存开始"); BizStorage storage = baseMapper.selectById(productId); storage.setUsed(storage.getUsed() + count); storage.setResidue(storage.getResidue() - count); baseMapper.updateById(storage); log.info("------->中扣减库存结束"); return AjaxResult.success("扣减库存成功"); } }

启动类增加注解

@EnableDiscoveryClient @EnableFeignClients @MapperScan("cn.tellsea.mapper") 6、测试下单业务

业务需求:下订单 -> 减库存 -> 扣余额 -> 改订单状态

(1)检查服务启动结果

启动三个 服务 检查 Nacos 的服务注册

(2)正常情况下单

数据库请求之前的数据 账户 订单

库存

访问线面连接下单

http://localhost:8008/bizOrder/createOrder?userId=1&productId=1&count=10&money=100

返回结果下单成功 账户:扣减

订单:创建完成

库存:扣减

(3)出错情况下单

在 spring-cloud-alibaba-boot-seata-account 模块的扣减账户余额中增加线程休眠

@Override public AjaxResult decrease(Long userId, BigDecimal money) { log.info("------->扣减余额开始"); //模拟超时异常,全局事务回滚 //暂停几秒钟线程 try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } BizAccount account = baseMapper.selectById(userId); account.setResidue(BigDecimalUtils.subtract(account.getResidue(), money)); account.setUsed(BigDecimalUtils.add(account.getUsed(), money)); baseMapper.updateById(account); log.info("------->扣减余额结束"); return AjaxResult.success("扣减余额成功"); }

重新访问下单连接

http://localhost:8008/bizOrder/createOrder?userId=1&productId=1&count=10&money=100

报错,因为 OpenFeign 默认调用时限为 1 秒 账户:余额不变 订单:已创建,但未完成 检查商品库存,丢失了!!!

(4)增加 Seata 事物

在创建订单的接口上增加全局事物注解

@GlobalTransactional(name = "tellsea_tx_group", rollbackFor = Exception.class)

重启服务 再次调用

http://localhost:8008/bizOrder/createOrder?userId=1&productId=1&count=10&money=100

同样的报错

账户:未变动

订单:未变动

库存:未变动 到此,Spring Cloud Alibaba Seata 分布式事物,控制成功

7、常见报错 (1)endpoint format should like ip:port

启动服务时,发现报错

2021-03-02 16:22:09.693 ERROR 8384 --- [ main] i.s.c.r.netty.NettyClientChannelManager : Failed to get available servers: endpoint format should like ip:port java.lang.IllegalArgumentException: endpoint format should like ip:port at io.seata.discovery.registry.FileRegistryServiceImpl.lookup(FileRegistryServiceImpl.java:95) ~[seata-all-1.3.0.jar:1.3.0] at io.seata.core.rpc.netty.NettyClientChannelManager.getAvailServerList(NettyClientChannelManager.java:217) ~[seata-all-1.3.0.jar:1.3.0] at io.seata.core.rpc.netty.NettyClientChannelManager.reconnect(NettyClientChannelManager.java:162) ~[seata-all-1.3.0.jar:1.3.0] at io.seata.core.rpc.netty.RmNettyRemotingClient.registerResource(RmNettyRemotingClient.java:181) [seata-all-1.3.0.jar:1.3.0] at io.seata.rm.AbstractResourceManager.registerResource(AbstractResourceManager.java:121) [seata-all-1.3.0.jar:1.3.0] at io.seata.rm.datasource.DataSourceManager.registerResource(DataSourceManager.java:146) [seata-all-1.3.0.jar:1.3.0] at io.seata.rm.DefaultResourceManager.registerResource(DefaultResourceManager.java:114) [seata-all-1.3.0.jar:1.3.0]

本文使用的 seata 依赖是 spring cloud alibaba seata,所以配置信息应该在 alibaba 下

tellsea_tx_group:自定义的组名称,与 vgroupMapping. 的点之后的名称对应seata 版本的不同,vgroupMapping 可能是 vgroup-mapping,这个直接看源码就知道了 错误版本 spring: cloud: # Seata配置 seata: tx-service-group: tellsea_tx_group 正确版本 spring: cloud: alibaba: # Seata配置 seata: tx-service-group: tellsea_tx_group 微信公众号


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Spring #Cloud #AlibabaSeata #分布式事务 #文章目录Spring #分布式事务1Spring