赞
踩
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC(类似2PC)、SAGA(长事务解决方案、基于状态机),为用户打造一站式的分布式解决方案。
AT模式同tx-lcn类似,通过代理底层数据库连接,控制数据库事务的提交与回滚(必须依赖数据库);当然seate由于是由阿里维护的,同时支持多种注册中心,zookeeper、eureka等。
名词解释: TC 事务协调者、TM 事务管理器、RM 资源管理器、Microservices 微服务、DB 数据库
参考链接:
seate模板:seata-samples/springcloud-eureka-feign-mybatis-seata at master · seata/seata-samples · GitHub;
seate快速使用:Quick Start
eureka、seate-0.8.0服务端、微服务1(hello)、微服务2(feign-consumer)
spring boot:2.1.8.RELEASE
spring cloud:Greenwich.SR2
代码链接:GitHub - kickTec/springCloudDemo at transaction-seate
csdn链接:transaction-seate.rar-Java文档类资源-CSDN下载
主要指定host,多个网卡自动绑定IP有时不对
- @Parameter(names = "--help", help = true)
- private boolean help;
- @Parameter(names = {"--host", "-h"}, description = "The ip to register to registry center.", order = 1)
- private String host;
- @Parameter(names = {"--port", "-p"}, description = "The port to listen.", order = 2)
- private int port = SERVER_DEFAULT_PORT;
- @Parameter(names = {"--storeMode", "-m"}, description = "log store mode : file, db", order = 3)
- private String storeMode;
- @Parameter(names = {"--serverNode", "-n"}, description = "server node id, such as 1, 2, 3.it will be generated according to the snowflake by default", order = 4)
- private Long serverNode;
- @Parameter(names = {"--seataEnv", "-e"}, description = "The name used for multi-configuration isolation.",
- order = 5)
windows启动seate服务器
seata-server.bat -h 192.168.0.18
maven配置
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.8.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.kenick</groupId>
- <artifactId>feign-consumer</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>feign-consumer</name>
- <description>feign-consumer</description>
-
- <properties>
- <java.version>1.8</java.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <!--数据库-->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.0.0</version>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- </dependency>
-
- <!-- pageHelper分页插件 -->
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper</artifactId>
- <version>4.0.0</version>
- </dependency>
-
- <!--druid-->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.10</version>
- <exclusions>
- <exclusion>
- <artifactId>slf4j-api</artifactId>
- <groupId>org.slf4j</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <!--lombok-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.8</version>
- </dependency>
-
- <!--seata-->
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-seata</artifactId>
- <version>2.1.0.RELEASE</version>
- <exclusions>
- <exclusion>
- <artifactId>seata-all</artifactId>
- <groupId>io.seata</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>io.seata</groupId>
- <artifactId>seata-all</artifactId>
- <version>1.2.0</version>
- </dependency>
-
- <!--eureka client-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
-
- <!--feign-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
- </dependencies>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Greenwich.SR2</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
seate特殊配置(seate服务器和微服务指定相同的tx-service-group):
spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group
file.conf文件中设置:
- #transaction service group mapping
- vgroupMapping.my_test_tx_group = "default"
- #only support when registry.type=file, please don't set multiple addresses
- default.grouplist = "192.168.0.18:8091"
register.conf中指定使用eureka:
- registry {
- # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
- type = "eureka"
-
- nacos {
- serverAddr = "localhost"
- namespace = "public"
- cluster = "default"
- }
- eureka {
- serviceUrl = "http://192.168.0.105:8888/eureka"
- application = "default"
- weight = "1"
- }
由于seate AT模式是通过代理数据库连接方式实现的,在每个service服务中都需要进行如下配置:
- /**
- * 数据源代理
- */
- @Configuration
- public class DataSourceConfiguration {
-
- @Bean
- @ConfigurationProperties(prefix = "spring.datasource")
- public DataSource druidDataSource(){
- return new DruidDataSource();
- }
-
- @Primary
- @Bean("dataSource")
- public DataSourceProxy dataSource(DataSource druidDataSource){
- return new DataSourceProxy(druidDataSource);
- }
-
- @Bean
- public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
- SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
- sqlSessionFactoryBean.setDataSource(dataSourceProxy);
- sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
- .getResources("classpath:mybatis/mapping/*Mapper.xml"));
- sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
- return sqlSessionFactoryBean.getObject();
- }
-
- }
全局事务使用,在service上添加注释
- @GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
- @Override
- public int saveUser(String userId, String name, int age) {
- logger.debug("本地开始保存用户!");
- User user = new User();
- user.setUserId(userId);
- user.setName(name);
- user.setAge(age);
- int ret = userMapper.insert(user);
- logger.debug("本地开始保存用户结果:" + ret);
-
- logger.debug("开始远程调用helloservice!");
- String remoteRet = helloService.addUser("remote_hello" + userId, name, age);
- logger.debug("远程调用helloservice结果:" + remoteRet);
-
- // 产生异常
- // int num = 1/0;
- return ret;
- }
其它的请参考项目代码配置。
调用feign-consumer工程的addUser接口,接口逻辑:先在本地保存用户,再调用hello服务的保存用户接口,相当于一次调用保存2了个用户信息。
正常流程
调用feign-consumer接口(192.168.0.18:4001/addUser),先在当前服务添加用户,再调用另一个微服务hello添加用户;2个用户信息添加成功;全局事务执行情况见下图。
feign-consumer日志
hello日志
异常流程:两次用户都保存成功后,后续feign-consumer 服务异常,最终两个工程都进行了回退。
feign-consumer日志
hello日志
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。