springcloud seata(1.6.1版本)
一、下载Seata,地址:下载中心
二、解压部署
1、进入conf目录修改配置文件,依据 application.example.yml 文件为样例,修改application.yml
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash
console:
user:
username: seata
password: seata
seata:
# 配置中心,以下是以nacos为配置中心
config:
# support: nacos, consul, apollo, zk, etcd3
type: nacos
nacos:
server-addr: 192.168.3.133:8848
# 以下namespace命名空间,需要在nacos中手动创建
namespace: 53e24698-1032-41cc-966f-129931d10ec9
group: SHOP_GROUP
username: nacos
password: nacos
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
data-id: seataServer.properties
# 注册中共新,以下以nacos为注册中心
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
application: seata-server
server-addr: 192.168.3.133:8848
group: SHOP_GROUP
# 以下namespace命名空间,需要在nacos中手动创建
namespace: 53e24698-1032-41cc-966f-129931d10ec9
cluster: default
username: nacos
password: nacos
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
# 选择存储模式
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
dbType: mysql
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
user: root
password: root
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
2. 进入script目录下的config-center对文件config.txt进行修改后,将其远程部署到nacos上,执行以下命令(如果windows,执行:nacos-config.py 命令来部署)
nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 在nacos上的命名空间id -u nacos账号 -w nacos密码
部署成功如下:

3. 新建seata数据库,进入script目录下server->db,选择对应的数据库文件
4. 启动seata服务,进入bin目录,点击相应的启动脚本
三、 springCloud加入seata
1. pom中引入依赖
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2021.1</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 我这边测试发下,如果不引入以下依赖的话,默认自己引入的版本比较低,然后会出现兼容问题 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-core</artifactId>
<version>1.6.1</version>
</dependency>
2. 新建多个微服务项目,如下:

3. 在nacos上配置三个微服务对应的参数(演示的微服务以nacos为注册配置中心) ,配置如下(三个微服务的配置基本一致,其中application.name的名字不 一样,数据库不一样,此处演示用了3个不同的数据库):
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
config-location: classpath:mapper/config/sqlMapConfig.xml
spring:
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
application:
name: open-seata-demo1
profiles:
active: dev
cloud:
inetutils:
preferred-networks: ^192\.168\.3\.[\d]+$
nacos:
config:
server-addr: 192.168.3.133:8848
group: gongshang_open_api
file-extension: yml
enabled: true
discovery:
server-addr: 192.168.3.133:8848
group: gongshang_open_api
sentinel:
transport:
# 配置Sentinel dashborad地址
dashboard: http://192.168.3.133:8080
port: 8719
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
#业务中台主库
master:
url: jdbc:mysql://127.0.0.1:3306/business_platform_demo?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
database: 0
host: 127.0.0.1
port: 6379
password:
max-active: 100
max-wait: 1000
management:
endpoints:
web:
exposure:
include: '*'
swagger:
title: open-seata-demo1
scanpackages: com.cn
logging:
level:
com.cn: error
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
# 打开sentinel对feign的支持
feign:
sentinel:
enabled: true
# 服务超时时间设置
ribbon:
#读超时时间
ReadTimeout: 5000
#连接超时时间
ConnectTimeout: 1000
#同一台实例最大重试次数,不包括首次调用
MaxAutoRetries: 1
#重试负载均衡其他的实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 1
#是否所有操作都重试
OkToRetryOnAllOperations: false
rocketmq:
nameServer: 192.168.3.133:9876
group: openapi-logs
global:
fileDomain: xxxxx
# seata配置
seata:
enabled: true
# Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name}
# Seata 事务组编号,用于 TC 集群名
tx-service-group: ${spring.application.name}-group
# 开启自动代理
enable-auto-data-source-proxy: true
# 服务配置项
service:
# 虚拟组和分组的映射
vgroup-mapping:
gulimall-order-group: default
config:
type: nacos
nacos:
serverAddr: 192.168.3.133:8848
group: SHOP_GROUP
# 以下命名空间ID与上文的均保持一致
namespace: 53e24698-1032-41cc-966f-129931d10ec9
registry:
type: nacos
nacos:
application: seata-server
server-addr: 192.168.3.133:8848
# 以下命名空间ID与上文的均保持一致
namespace: 53e24698-1032-41cc-966f-129931d10ec9
group: SHOP_GROUP
demo:
exception: false

4. 在naocs上增加以下三个配置:service.vgroupMapping.open-seata-demo1-group、service.vgroupMapping.open-seata-demo2-group、service.vgroupMapping.open-seata-demo3-group




5. 编写微服务: open-seata-demo3
mapper文件
package com.cn.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cn.web.entity.OnlineMessageEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* description: IOnmessageMapper <br>
* date: 23.3.20 16:28 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Mapper
public interface IOnmessageMapper extends BaseMapper<OnlineMessageEntity> {
}
service文件
package com.cn.web.service;
import com.cn.exception.MyException;
import com.cn.util.DateUtil;
import com.cn.util.SnowflakeIdWorkerUtil;
import com.cn.web.entity.GlobalDemoConfig;
import com.cn.web.entity.OnlineMessageEntity;
import com.cn.web.mapper.IOnmessageMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* description: OnMessageService <br>
* date: 23.3.20 16:28 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Service
@Slf4j
public class OnMessageService {
@Autowired
private IOnmessageMapper onmessageMapper;
@Autowired
private GlobalDemoConfig globalDemoConfig;
@Transactional
public void add(OnlineMessageEntity msg) {
msg.setId(SnowflakeIdWorkerUtil.getId());
msg.setCreateDate(DateUtil.getTime("yyyy-MM-dd HH:mm:ss"));
if (StringUtils.isEmpty(msg.getImgs())) {
msg.setImgs("");
}
this.onmessageMapper.insert(msg);
//动态控制抛出异常
if (globalDemoConfig.isException()) {
throw new MyException("在线留言失败");
}
}
}
controller
package com.cn.web.controller;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.OnlineMessageEntity;
import com.cn.web.service.OnMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* description: OnMessageController <br>
* date: 23.3.22 16:08 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@RestController
@RequestMapping(value = "seata3")
public class OnMessageController {
@Autowired
private OnMessageService onMessageService;
@PostMapping(value = "save")
public ResultMsg save(
@RequestBody OnlineMessageEntity info
) {
this.onMessageService.add(info);
return ResultMsg.builder();
}
}
6. 编写微服务:open-seata-demo2
mapper
package com.cn.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cn.web.entity.MsgEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* description: IMsgMapper <br>
* date: 23.3.17 17:29 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Mapper
public interface IMsgMapper extends BaseMapper<MsgEntity> {
}
service文件
package com.cn.web.service;
import com.cn.exception.MyException;
import com.cn.util.DateUtil;
import com.cn.util.SnowflakeIdWorkerUtil;
import com.cn.web.entity.GlobalDemoConfig;
import com.cn.web.entity.MsgEntity;
import com.cn.web.entity.OnlineMessageEntity;
import com.cn.web.mapper.IMsgMapper;
import com.cn.web.plugin.OpenSeataDemo2Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* description: MsgService <br>
* date: 23.3.17 17:28 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Service
@Slf4j
public class MsgService {
@Autowired
private IMsgMapper msgMapper;
@Autowired
private OpenSeataDemo2Service openSeataDemo2Service;
@Autowired
private GlobalDemoConfig globalDemoConfig;
@Transactional
public void saveTmp(MsgEntity info) {
info.setId(SnowflakeIdWorkerUtil.getId());
info.setCreateTime(DateUtil.getTime("yyyy-MM-dd HH:mm:ss"));
this.msgMapper.insert(info);
//调用微服务open-seata-demo3
OnlineMessageEntity msg = new OnlineMessageEntity();
msg.setTitle("在线留言").setContent("在线留言内容啊啊啊");
var result = openSeataDemo2Service.save(msg);
if (result.getCode() != 200) {
throw new MyException(result.getMsg());
}
if (globalDemoConfig.isException()) {
throw new MyException("保存通知失败");
}
}
}
controller
package com.cn.web.controller;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.MsgEntity;
import com.cn.web.service.MsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* description: MsgController <br>
* date: 23.3.22 16:01 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@RestController
@RequestMapping(value = "seata2")
public class MsgController {
@Autowired
private MsgService msgService;
@PostMapping(value = "save")
public ResultMsg save(
@RequestBody MsgEntity info
) {
msgService.saveTmp(info);
return ResultMsg.builder();
}
}
微服务open-seata-demo3
package com.cn.web.plugin;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.MsgEntity;
import com.cn.web.entity.OnlineMessageEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* description: OpenSeataDemo2Service <br>
* date: 23.3.22 16:00 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@FeignClient(value = "open-seata-demo3", fallback = OpenSeataDemo2FallbackImpl.class)
public interface OpenSeataDemo2Service {
@PostMapping(value = "seata3/save")
ResultMsg save(@RequestBody OnlineMessageEntity info);
}
package com.cn.web.plugin;
import com.cn.exception.MyException;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.OnlineMessageEntity;
import org.springframework.stereotype.Component;
/**
* description: OpenSeataDemo2FallbackImpl <br>
* date: 23.3.22 16:04 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Component
public class OpenSeataDemo2FallbackImpl implements OpenSeataDemo2Service {
@Override
public ResultMsg save(OnlineMessageEntity info) {
throw new MyException("添加msg失败");
}
}
结构如下:

7. 编写微服务:open-seata-demo1
mapper
package com.cn.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cn.web.entity.PortalUserEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* description: IUserMapper <br>
* date: 23.3.16 9:50 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Mapper
public interface IUserMapper extends BaseMapper<PortalUserEntity> {
}
service
package com.cn.web.service;
import com.cn.exception.MyException;
import com.cn.util.DateUtil;
import com.cn.util.SnowflakeIdWorkerUtil;
import com.cn.web.entity.GlobalDemoConfig;
import com.cn.web.entity.MsgEntity;
import com.cn.web.entity.PortalUserEntity;
import com.cn.web.mapper.IUserMapper;
import com.cn.web.plugin.OpenSeataDemo2Service;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* description: UserService <br>
* date: 23.3.16 9:51 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Service
@Slf4j
public class UserService {
@Autowired
private IUserMapper userMapper;
@Autowired
private OpenSeataDemo2Service openSeataDemo2Service;
@Autowired
private GlobalDemoConfig globalDemoConfig;
@Transactional
@GlobalTransactional(rollbackFor = Exception.class)
public void saveTmp(PortalUserEntity info) {
info.setId(SnowflakeIdWorkerUtil.getId());
info.setAddTime(DateUtil.getTime("yyyy-MM-dd HH:mm:ss"));
this.userMapper.insert(info);
//调用微服务:open-seata-demo2
MsgEntity msg = new MsgEntity();
msg.setTitle("xxx测试啊").setContent("开始的发哈检索到访哈酒");
var result = openSeataDemo2Service.save(msg);
if (result.getCode() != 200) {
throw new MyException(result.getMsg());
}
if (globalDemoConfig.isException()) {
throw new MyException("回滚人员信息");
}
}
}
controller
package com.cn.web.controller;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.PortalUserEntity;
import com.cn.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* description: DemoController <br>
* date: 23.3.22 16:06 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@RestController
@RequestMapping(value = "seata1")
public class DemoController {
@Autowired
private UserService userServices;
@PostMapping(value = "save")
public ResultMsg save(
@RequestBody PortalUserEntity info
) {
this.userServices.saveTmp(info);
return ResultMsg.builder();
}
}
微服务open-seata-demo2
package com.cn.web.plugin;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.MsgEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* description: OpenSeataDemo2Service <br>
* date: 23.3.22 16:00 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@FeignClient(value = "open-seata-demo2", fallback = OpenSeataDemo2FallbackImpl.class)
public interface OpenSeataDemo2Service {
@PostMapping(value = "seata2/save")
ResultMsg save(@RequestBody MsgEntity info);
}
package com.cn.web.plugin;
import com.cn.exception.MyException;
import com.cn.msg.ResultMsg;
import com.cn.web.entity.MsgEntity;
import org.springframework.stereotype.Component;
/**
* description: OpenSeataDemo2FallbackImpl <br>
* date: 23.3.22 16:04 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Component
public class OpenSeataDemo2FallbackImpl implements OpenSeataDemo2Service {
@Override
public ResultMsg save(MsgEntity info) {
throw new MyException("添加失败");
}
}
结构如下

8. 启动三个微服务,以微服务open-seata-demo1为入口,然后在nacos中动态修改参数:demo.exception来控制抛出异常,测试实际效果。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)