微服务: Seata AT springCloud整合分布式事务以配置方式(中篇)

目录

上篇: 安装seata 并启动成功的传送门

1. 前言: 

2. springCloud 使用seata at 的步骤如下

第一步 查看springCloud版本

第二步添加maven依赖

第三步 添加yml配置

第四步: 配置数据源(druid) 

第五步 修复一个警告

 第六步: 启动后 看看日志是否成功


上篇: 安装seata 并启动成功的传送门

传送门===> 微服务: Seata AT 分布式事务以及配置方式(上篇)

1. 前言: 

-> Seata AT(Automatic Transaction) 分布式事务解决方案之一

主要解决分布式系统中的事务一致性问题。在传统的分布式系统中,当多个服务之间需要进行事务操作时,每个服务都需要自己实现分布式事务的管理和协调,这样就容易出现事务不一致的情况。而 Seata AT 利用了全局事务和本地事务的概念,将事务的管理和协调工作集中在 Seata Server 上,实现了分布式事务的一致性和可靠性。具体来说,Seata AT 解决了以下问题:

  1. 分布式事务协调:Seata AT 提供了一个全局事务管理器,负责协调和管理多个本地事务,保证所有分支事务的一致性。

  2. 事务隔离性和原子性:Seata AT 在全局事务提交时,保证所有分支事务都已成功提交,否则全局事务回滚。这样可保证事务的隔离性和原子性。

  3. 事务恢复机制:Seata AT 提供了一个事务日志存储服务,能够恢复因为网络或其他异常导致的事务失败状态,提高了系统的健壮性。

  4. 分布式锁机制:Seata AT 使用分布式锁机制,保证在多个事务同时操作同一个资源时,能够避免冲突和数据不一致性。

 -> seata AT 事务概念:  

TC((Transaction Coordinator)): 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM(Transaction Manager):事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager):资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

2. springCloud 使用seata at 的步骤如下

第一步 查看springCloud版本

第二步添加maven依赖


         <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

第三步 添加yml配置

#pzy 配置分布式事务 
seata:
  enabled: true # 1.0新特性,需要依赖seata-spring-boot-starter 默认为true
  enable-auto-data-source-proxy: true  # 牵扯到回滚
  tx-service-group: seata_group  # 需要与config.txt中的 service.vgroupMapping.seata_group=default保持一致
  server:
    vgroup-mapping:
      seata_group: default # 需要与config.txt中的 service.vgroupMapping.seata_group=default 保持一致
    #grouplist:
    #  default: 127.0.0.1:8091
    disable-global-transaction: false
  registry:  ## 注册中心
    type: nacos #注册nacos
    nacos:
      application: seata-server  #nacos中seata-server启动注册成功后的服务名称
      server-addr: *:8848
      username: *
      password: *
      group: SEATA_GROUP
      namespace: 49b38634-8a78-4216-a80c-7181976301c5
  config: ## 配置中心  与register.conf文件中的保持一致
    type: nacos
    nacos:
      server-addr: *:8848
      group: *#与register.conf文件中的保持一致
      username: *
      password: *
      namespace: 49b38634-8a78-4216-a80c-7181976301c5

第四步: 配置数据源(druid) 

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import lombok.extern.slf4j.Slf4j;



import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;



import javax.sql.DataSource;

/**
 * 配置数据源,使用seata对数据源做代理
 */
@Slf4j
@Configuration
public class DataSourcesConfig {

// V1版本
//    @Value("${mybatis-plus.mapper-locations}")
//    private String mapperLocations;
//
//    @Bean
//    @ConfigurationProperties(prefix = "spring.datasource")
//    public DataSource druidDataSource() {
//        return new DruidDataSource();
//    }
//
//    /**
//     * 使用 io.seata.rm.datasource.DataSourceProxy
//     * @param druidDataSource
//     * @return
//     */
//    @Bean
//    public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
//        return new DataSourceProxy(druidDataSource);
//    }
//
//    @Bean
//    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
//        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
//        bean.setDataSource(dataSourceProxy);
//        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//        bean.setMapperLocations(resolver.getResources(mapperLocations));
//        return bean.getObject();
//    }

    //V2 版本
    @Autowired
    private DataSourceProperties dataSourceProperties;

    @Bean(name = "dataSource") // 声明其为Bean实例
    @Primary // 在同样的DataSource中,首先使用被标注的DataSource
    public DataSource druidDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        log.info("dataSourceProperties.getUrl():{}", dataSourceProperties.getUrl());
        druidDataSource.setUrl(dataSourceProperties.getUrl());
        druidDataSource.setUsername(dataSourceProperties.getUsername());
        druidDataSource.setPassword(dataSourceProperties.getPassword());
        druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        druidDataSource.setInitialSize(0);
        druidDataSource.setMaxActive(180);
        druidDataSource.setMaxWait(60000);
        druidDataSource.setMinIdle(0);
        druidDataSource.setValidationQuery("Select 1 from DUAL");
        druidDataSource.setTestOnBorrow(false);
        druidDataSource.setTestOnReturn(false);
        druidDataSource.setTestWhileIdle(true);
        druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
        druidDataSource.setMinEvictableIdleTimeMillis(25200000);
        druidDataSource.setRemoveAbandoned(true);
        druidDataSource.setRemoveAbandonedTimeout(1800);
        druidDataSource.setLogAbandoned(true);
        log.info("装载dataSource........");
        return new DataSourceProxy(druidDataSource);
    }


}

[如果是mybatis plus 分页失效的, 部分组件失效的, 请使用这套]

第五步 修复一个警告

Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be....

undertow 设置一下buffer pool,不然他就使用默认,启动时会出现警告

import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

/**
 *
 *
 * 解决方案一: 配置文件
 * 解决方案二: application.properties的配置
 *
 * @author: pzy
 * @date: 2023-05-19
 * @description: 解决启动io.undertow.websockets.jsr UT026010: Buffer pool was not
 * set on WebSocketDeploymentInfo, the default pool will be used的警告
 */
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
            webSocketDeploymentInfo.setBuffers(
                    new DefaultByteBufferPool(false, 1024)
//                    new DefaultByteBufferPool(false, 1024,20,4)
            );
            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
        });
    }
}

 第六步: 启动后 看看日志是否成功


检查: 

-> 检查undo_log数据库是否存在未删除的数据

-> 看控制台是否有rm tm字样 commit rollback等 

-> 在远调的服务中写点报错 看看是否回滚成功

猜你喜欢

转载自blog.csdn.net/pingzhuyan/article/details/130801805
今日推荐