springcloud整合seata1.3.0实现分布式事务+nacos1.3.1注册中心

什么是事务:

事务就是保证数据库交易可靠性的一种机制
事务的四种特性
A 原子性: 事务操作要么全部成功,要么全部失败
C 一致性: 一个事务在执行前后数据库的状态都必须一致
I 隔离型: 事务相互隔离,不能被干扰
D 持久性:对数据库的操作成功以后,永久有效

为什么要使用分布式事务:

因为事务无法满足分布式下的数据一致性,所以出现了分布式事务

什么是分布式事务:

分布式事务就是为了解决多数据库下实现数据一致性
首先我们要知道CAP定理 CAP定理也是三者不可兼得
C 一致性 在分布式系统中数据必须都是同一样的值
A 可用性 在集群中一部分节点故障后是否还可以相应客户端
P 分区容错性 区间通信可能会失败

一般来说,分区容错无法避免,所以认为P一定成立,所以要么AP,要么CP

什么是seata:

seata是一个alibaba开发出得分布式事务解决方法,支持了AT,TCC,SAGA,XA事务模式

详细信息请移步官网自行了解.

我使用是使用了AT强一致性二阶段提交的事务模式

seata服务端:

**使用seata请先下载服务端 我自己使用的是1.3.0 注册中心是nacos1.3.1

nacos下载

修改配置文件application.properties把注释掉的这个打开修改成对应的用户密码
然后把conf下的nacos-mysql.sql文件在mysql中执行 修改成对应的数据库名

### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root

然后单机启动 ./startup.sh -m standalone

访问 localhost:8848/nacos就可以看到nacos启动成功

在这里插入图片描述

seata下载

在1.0.0以后一些配置文件都不在下载的包里,要自行下载

nacos-config.sh和config.txt下载

config.txt进去就可以看到,.sh文件下级目录可以找到

在这里插入图片描述

.sh下载过放到conf下,config.txt放到conf同级的目录

然后修改txt文件,将.sh执行,把配置加载到nacos中,启动时要加上端口号

在nacos中就可以看到加载了进来

在这里插入图片描述

修改配置文件的数据库配置,然后这里的组要跟client中的组对应,先记下来

在这里插入图片描述

seata需要的数据库表下载

undo_log下载

要在需要的每个数据库都添加undo_log表

修改file.conf和registry.conf文件

改成db,修改数据库信息
在这里插入图片描述
把注册中心修改nacos
在这里插入图片描述
下边的配置使用file文件就可以
在这里插入图片描述

以db方式启动

在bin目录下启动seata-server.sh -m db

可以看到seata注册到了nacos

在这里插入图片描述

最后文件是这样子的

在这里插入图片描述

seata客户端:

<dependency> //springboot包
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>2.2.6.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!--spring cloud Hoxton.SR7-->
			<dependency> //springcloud包
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Hoxton.SR7</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!--spring cloud alibaba 2.1.1.RELEASE-->
			<dependency> //alibabacloud包
				<groupId>com.alibaba.cloud</groupId>
				<artifactId>spring-cloud-alibaba-dependencies</artifactId>
				<version>2.2.1.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			
		<dependency>//seata包
        <groupId>io.seata</groupId>
        <artifactId>seata-spring-boot-starter</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>io.seata</groupId>
        <artifactId>seata-all</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        <version>2.2.1.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>io.seata</groupId>
                <artifactId>seata-spring-boot-starter</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
<dependency>//nacos注册中心
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

yml配置文件:

seata:
  enabled: true
  application-id: system-exporta  //一般可以用服务名称 要唯一
  tx-service-group: my_group   //要和服务端的组对应
  config:
    type: nacos  
    nacos:
      namespace:
      server-addr: localhost:8848
      group: SEATA_GROUP
      username: nacos
      password: nacos
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: localhost:8848
      group: SEATA_GROUP
      namespace:
      username: nacos
      password: nacos
  service:
    vgroup-mapping:
      my_group: default  和服务端的对应

在启动类上要把自动的数据源关闭,然后自己定义数据原
在这里插入图片描述
mybatis和mybatis-plus配置不同,千万别搞错

mybatis:

@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(“你的xml文件位置”));
        return bean.getObject();
    }

mybatis-plus:

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

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

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSourceProxy);
        bean.setTypeAliasesPackage("包路径"); //比如 com.xxx.xxx.mapper
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        bean.setConfiguration(configuration);
        return bean.getObject();
    }

**setTransactionFactory(new SpringManagedTransactionFactory())

这个配置是一个大坑,千万别加,找了一个星期为什么不回回滚

其余服务配置相同

然后使用就是在方法上加上一个

@GlobalTransactional(name = “save”,rollbackFor = Throwable.class)注解

被调用方不用加 加上注解就是一个TM,一个服务可以同时是一个TM和RM

name自己起,rollbackFor应该是接收到什么类型错误回滚

如果你在A服务的方法加了这个注解,然后调用了B服务,B服务报错的话是不会回滚的,必须要这个注解捕获到错误才可以回滚,可以在B方法抛出异常抛给A,这样就可以回滚**

启动一个服务:可以在服务端看到RM注册了进来

TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

RM通俗一点可以说是事务参与者

TC就是事务协调者

TM可以算是事务发起者

只是自己理解

在这里插入图片描述

启动第二个服务

在这里插入图片描述
在调用方打上断点:

在这里插入图片描述

参与的两张表都是空数据

在这里插入图片描述
在这里插入图片描述
断点后发现数据插了进去
在这里插入图片描述
在这里插入图片描述
然后放开断点,1/0会报错

idea打印回滚信息
在这里插入图片描述
服务端显示回滚成功

在这里插入图片描述
然后数据表里的数据会被回滚

完成

おすすめ

転載: blog.csdn.net/m0_48358308/article/details/109991307