seata 1.2版本分布式事务实战

seata 1.2版本分布式事务实战:

一、seata服务端注册并把配置信息配置在nacos配置中心:具体方法请参看这篇,里面同时包含数据库的sql脚本初始化:

seata配置相关

1、配置 nacos 成功后

2、启动后注册到配置中心:

 二、客户端consume服务创建:

1、、客户端consume相关jar导入:

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-cloud-nacos-client-consume-7100</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <!-- https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-seata -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

2、客户端consume注册到nacos配置:bootstrap.yml文件内容:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 172.21.3.158:8849
        namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      config: #这里一定记得配置
          server-addr: 172.21.3.158:8849
          namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
  application:
    name: consume

#seata相关配置
seata:
  enabled: true
  application-id: consume
  tx-service-group: my_test_tx_group
  enable-auto-data-source-proxy: true
  use-jdk-proxy: true
  config:
    type: nacos
    nacos:
      group: SEATA_GROUP
      server-addr: 172.21.3.158:8849
      namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      userName: "nacos"
      password: "nacos"
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 172.21.3.158:8849
      namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      userName: "nacos"
      password: "nacos"

server:
  port: 7100

 3、consume核心代码:


import com.nacos.consume.feign.IndexService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    IndexService indexService;


    @GlobalTransactional  //核心分布式事务注解
    public String update(String name) {
        String str = indexService.index();//远程调用的业务方法
        if(name.equals("nd"))//事务回滚的条件
            System.out.println("xxxxxxxxxxxx"+1/0);
        return str;
    }
}

远程调用的封装接口:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient("provide")
public interface IndexService {
    @GetMapping("/index")
    public String index();
}

控制层:


import com.nacos.consume.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class IndexController {

    @Autowired
    ProductService productService;

    @GetMapping("index")

    public String index(@RequestParam String name){
        String result =  productService.update(name);//进入业务层
        return result;
    }

4、启动comsum服务:

三、微服务provide创建:

1、pom导入基本完全一样:

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-cloud-nacos-client-provide-9100</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <!-- https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-seata -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2、核心配置也基本一样:

spring:
  application:
    name: provide
  cloud:
    nacos:
      discovery:
        server-addr: 172.21.3.158:8849
        namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      config:
        server-addr: 172.21.3.158:8849
        namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83


#设置feign的超时时间
feign:
  client:
    config:
      default:
        connectTimeout: 40000
        readTimeout: 40000

#seata相关配置
seata:
  enabled: true
  application-id: provide
  tx-service-group: my_test_tx_group
  enable-auto-data-source-proxy: true
  use-jdk-proxy: false
  config:
    type: nacos
    nacos:
      server-addr: 172.21.3.158:8849
      namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      group: SEATA_GROUP
      userName: ""
      password: ""
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 172.21.3.158:8849
      namespace: 23d0f9d9-096e-4fea-a548-e3ba778a6b83
      userName: ""
      password: ""
server:
  port: 9100

3、核心代码:

控制层:


import com.nacos.provide.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class IndexController {

    @Autowired
    StorageService storageService;
    @GetMapping("index")
    public String index(){
        storageService.update();//进入业务层
        return 9100+"index";
    }

业务层:


import com.nacos.provide.dao.StorageDao;
import com.nacos.provide.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StorageServiceImpl implements StorageService {

    @Autowired
    StorageDao storageDao;

    public void update() {
        storageDao.update();//进入dao层操作数据库
    }
}

DAO层:

import org.apache.ibatis.annotations.Update;

public interface StorageDao {
    @Update("update product set used=used+1")
    public int update();
}

数据源配置:


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@MapperScan("com.nacos.provide.dao")
@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource dataSource(){
        
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setPassword("nandao");
        dataSource.setUsername("nandao");
        dataSource.setUrl("jdbc:postgresql://10.130.16.2466:305188/nan-power?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8");

        dataSource.setMaxActive(2000);
        dataSource.setMaxWait(20000);
        return dataSource;
    }


    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        return sqlSessionFactoryBean.getObject();
    }
}

4、启动成功状态和consume一样。

四、测试接口:

1、发一个正常请求:http://localhost:7100/index?name=ddd

先断点:

seata

客户端:

查看rollback_info 的文本内容方式: 

SELECT *,CONVERT (rollback_info USING utf8) as info FROM undo_log;

放开断点后seata 服务端三张表数据和客户端undo_log表数据清空,业务数据成功,执行事务正常提交:

comsume日志:”

provide日志:

2、触发异常请求:http://localhost:7100/index?name=nd

依然断点到这里:

此时服务端和客户端数据库均有数据,业务数据也进行了第一阶段提交。继续往下走,执行结束:

抛异常,事务进行回滚,客户端执行反sql,业务表数据回到了从前;日志如下:

consume日志:

provide服务回滚日志:

实战demo结束,不明白的小伙伴可以留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值