内容快捷导航
一、Docker安装Seata
1、docker拉取seata镜像(注意Seata版本,具体参照自己的Spring Cloud)
2、启动容器
3、拷贝seata启动后的镜像文件文件至这里我放在mydata中
4、移除旧的容器
5、重新启动新容器
二、Seata配置修改(以Nacos作为注册中心,File作为配置文件)
1、进入resources目录
2、修改registry.conf文件
3、file.conf文件不用改,用默认的
4、重启seata-server容器
5、启动nacos查看效果
三、Seata分布式全局事务在Spring Cloud上的实践
1、导入依赖(这边我的seata版本用的是父项目版本控制中心的,直接解决版本依赖问题巴适)
2、修改applicaton配置文件
3、解决冲突
4、最后亲测可行
一、Docker安装Seata
1、docker拉取seata镜像(注意Seata版本,具体参照自己的Spring Cloud)
具体Docker官网查看:Docke Hub官网
docker pull seataio/seata-server:1.4.2
2、启动容器
docker run -d --name seata-server -p 8091:8091 seataio/seata-server:1.4.2
3、拷贝seata启动后的镜像文件文件至这里我放在mydata中
- 创建目录/mydata/seata
mkdir /mydata/seata
- 拷贝seata启动后的镜像文件至/mydata/seata
docker cp seata-server:/seata-server /mydata/seata
效果图:
- 将seata-server移动出来(主要我看它嵌套在里面不舒服)
mv seata-server/* .
rm -rf seata-server
4、移除旧的容器
docker rm -f seata-server
5、重新启动新容器
docker run -d \
--restart always \
--privileged=true \
--name seata-server \
-p 8091:8091 \
-v /mydata/seata:/seata-server \
-e SEATA_IP=[访问linux的ip地址] \
-e SEATA_PORT=8091 \
seataio/seata-server:1.4.2
我的访问ip是192.168.56.10,所以就如下
docker run -d \
--restart always \
--privileged=true \
--name seata-server \
-p 8091:8091 \
-v /mydata/seata:/seata-server \
-e SEATA_IP=192.168.56.10 \
-e SEATA_PORT=8091 \
seataio/seata-server:1.4.2
二、Seata配置修改(以Nacos作为注册中心,File作为配置文件)
1、进入resources目录
cd /mydata/seata/resources
2、修改registry.conf文件
vi registry.conf
选择nacos作为注册中心,并填写nacos的账号和密码
默认type="file"不要修改,对应的配置文件就是file{name=“file.conf”}中的file.conf
3、file.conf文件不用改,用默认的
4、重启seata-server容器
5、启动nacos查看效果
三、Seata分布式全局事务在Spring Cloud上的实践
1、导入依赖(这边我的seata版本用的是父项目版本控制中心的,直接解决版本依赖问题巴适)
父项目版本中心的依赖(对应docker中下载的是seata:1.4.2)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
2、修改applicaton配置文件
由于我用的是Mybatis-Plus以及DruidDataSource,所以要取消对应的自动代理数据源,否则会与Mybatis-Plus的增强组件冲突导致报错,具体报错名称可看:Seata与Mybatis-plus冲突导致其组件全失效
spring:
cloud:
alibaba:
seata:
tx-service-group: mall-group
# 不然使用druid数据源会冲突从而报错
# enable-auto-data-source-proxy就是表示不使用自动代理数据源,否则会与 多数据源、Mybatis-Plus冲突
seata:
enabled: true
enable-auto-data-source-proxy: false
service:
grouplist:
default: 192.168.56.10:8091 # seata-server服务器地址,默认是 8091
enable-degrade: false # 降级,当前不支持
disable-global-transaction: false # 启用全局事务
vgroup-mapping:
mall-group: default # 事务分组,默认:${spring.applicaiton.name}-seata-service-group,可以随便写
3、解决冲突
具体冲突原因和 Seata DataSourceProxy 的使用,请看这里:一文讲清楚 seata DataSourceProxy 的使用
具体的配置文件如下:(特别注意在分布式服务中所有用到Seata以及相关Mybatis-Plus增强功能的都需要引入下面的配置文件,不然全局事务回滚会失效哦)
@Configuration
@ConditionalOnClass(DruidDataSource.class)
//@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MyDataSourceConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
// 请求页面大于最大页面,true返回到首页,false继续请求,默认false
paginationInnerInterceptor.setOverflow(true);
// 设置最大单页限制数量,默认500
paginationInnerInterceptor.setMaxLimit(500l);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
// 通过自动注入DataSourceProperties,获取properties/yml配置文件有关DataSource的配置信息
@Resource
private DataSourceProperties dataSourceProperties;
@Bean
public DataSourceProxy dataSourceProxy() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(dataSourceProperties.getUrl());
dataSource.setUsername(dataSourceProperties.getUsername());
dataSource.setPassword(dataSourceProperties.getPassword());
dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
// dataSource.setInitialSize(1);
// dataSource.setMaxActive(120);
// dataSource.setMaxWait(60000);
// dataSource.setMinIdle(1);
// dataSource.setValidationQuery("Select 1 from DUAL");
// dataSource.setTestOnBorrow(false);
// dataSource.setTestOnReturn(false);
// dataSource.setTestWhileIdle(true);
// dataSource.setTimeBetweenEvictionRunsMillis(60000);
// dataSource.setMinEvictableIdleTimeMillis(25200000);
// dataSource.setRemoveAbandoned(true);
// dataSource.setRemoveAbandonedTimeout(1800);
// dataSource.setLogAbandoned(true);
return new DataSourceProxy(dataSource);
}
// 通过自动注入MybatisPlusProperties,获取properties/yml配置文件有关Mybatis-Plus的配置信息
@Resource
private MybatisPlusProperties properties;
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
// DataSource dataSourceProxy = new DataSourceProxy(druidDataSource);
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSourceProxy);
bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// bean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
bean.setMapperLocations(resolver.getResources("classpath*:/mapper/**/*.xml"));
bean.setGlobalConfig(properties.getGlobalConfig());
SqlSessionFactory factory = null;
try {
factory = bean.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
return factory;
}
}
4、最后亲测可行
我的项目:首先在方法上加 @GlobalTransactional,订单服务(order)利用openFeign调用库存服务(ware),此时库存服务已经写入数据,库存++,由于订单服务中报错,然后全局事务回滚(订单数据和库存数据都回滚了)