本文介绍的是SpringCloudAlibaba整合的Seata

什么是Seata?

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。并且他平稳的经历了这么多年淘宝的双11,可以说十分强大。

第一步:下载Nacos和Seata

Nacos简单来说是一个服务注册中心,但他更加强大
Nacos下载地址:https://github.com/alibaba/nacos/releases 本文我用的是1.1.4版本 下载解压就好了
Nacos持久化这里就不讲解了
也可以不用nacos

Github上可能会很慢,我整理了一下,不用积分 可以吧下完点个赞就行

Seata下载地址https://github.com/seata/seata/releases 文本用的是 0.9.0 版本 建议用这个,因为1.0后环境配置不一样

进入conf文件夹

seata 得xa模式 实现demo_java


在mysql建一个seata库,把db_store.sql放在mysql执行一遍,执行完后打开file.conf文件

seata 得xa模式 实现demo_spring_02


往下滑

seata 得xa模式 实现demo_mysql_03


保存,再打开conf目录下的registry.conf

seata 得xa模式 实现demo_spring_04


OK,配置就到这了,接下来就是实践了

结合代码使用

我分了3个库,一个order订单库,一个account账户余额库,一个storage库存库,3个服务,业务流程:创建订单、减库存、扣除账户余额,业务你们随意
注意!!!!
在你所有需要的分布式事务回滚操作的业务数据库里创建undo_log表,sql语 句在Seata的conf文件里的db_undo_log.sql,
注意!!!!

首先是pom文件

<dependencies>
 	    <dependencies>
        <!-- Nacos       -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <!--  排除springbooot自带的的默认版本   使用自己seata版本对应的版本 -->
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>
<!--        这里版本要对应你seata的版本-->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>0.9.0</version>
        </dependency>
<!--             feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <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>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

接下来是yaml文件

spring:
   cloud:
    alibaba:
       seata:
        #记得与你conf目录下的file.conf之前修改那个vgroup_mapping.my_test_tx_group值
        tx-service-group: fsp_tx_group

Seata代理mybatis的datasource(数据源)

@Configuration
public class Mybatis {
    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Bean
    public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSourceProxy);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        bean.setMapperLocations(resolver.getResources(mapperLocations));
        return bean.getObject();
    }
}

注意!!!!

将seata Conf目录下的file.conf和registry.conf文件复制到项目的resource下,再将复制过来的file.conf文件,把mapping.后面的改为file.conf之前将default修改后的值

//mapping后面对应的是之前改的值    等于default就行
  vgroup_mapping.fsp_tx_group = "default"
@Override
    //在你需要回滚的方法加上@GlobalTransactional注解,name自取,
    //rollbackFor=Exception.class表示遇到错误就回滚
    @GlobalTransactional(name = "fsp-order-create",rollbackFor = Exception.class)
    public CommonResult<String> insert(TOrder tOrder) {
        log.info("---------------创建订单-------------------");
        this.tOrderDao.insert(tOrder);
        log.info("--------订单微服务开始减库存操作----------");
        tStorageService.decrease(tOrder.getProductId(),tOrder.getCount());
        log.info("-------------库存扣减成功------------------");
        log.info("-------------扣减账号余额-------------------");
        tAccountService.decrease(tOrder.getUserId(),tOrder.getMoney());
        log.info("--------------扣减成功----------------------");
        tOrderDao.update(tOrder);
        return new CommonResult<String>(200,"购买成功!","");
    }

进入解压Nacos进入bin文件启动startup,再进入Seata bin文件启动seata-server,之后启动项目