マイクロサービス: Seata AT springCloud は構成モードで分散トランザクションを統合します (パート 2)

目次

前: Seata をインストールしてポータルを正常に起動する

1 はじめに: 

2. springCloudがseataを使用する手順は次のとおりです。

最初のステップは、springCloud のバージョンを確認することです

2 番目のステップは、Maven の依存関係を追加することです。

3 番目のステップは、yml 構成を追加することです。

ステップ 4: データ ソース (druid) を構成する 

ステップ 5 警告を修正する

 ステップ 6: 起動後に成功したかどうかログを確認する


前: Seata をインストールしてポータルを正常に起動する

ポータル ===> マイクロサービス: Seata AT 分散トランザクションと構成方法 (パート 1)

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 ((トランザクション コーディネーター)): トランザクション コーディネーターは、
グローバル トランザクションとブランチ トランザクションの状態を維持し、グローバル トランザクションのコミットまたはロールバックを駆動します。
TM (トランザクション マネージャー): トランザクション マネージャーは、
グローバル トランザクションの範囲を定義します。つまり、グローバル トランザクションの開始、グローバル トランザクションのコミットまたはロールバックです。
RM (リソース マネージャー): リソース マネージャーは、
ブランチ トランザクションのリソースを管理し、TC と通信してブランチ トランザクションを登録し、ブランチ トランザクションのステータスを報告し、ブランチ トランザクションをコミットまたはロールバックします。

2. springCloudがseataを使用する手順は次のとおりです。

最初のステップは、springCloud のバージョンを確認することです

2 番目のステップは、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>

3 番目のステップは、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

ステップ 4: データ ソース (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 ページネーションが失敗する場合、一部のコンポーネントが失敗する場合は、このセットを使用してください]

ステップ 5 警告を修正する

バッファ プールが WebSocketDeploymentInfo に設定されていませんでした。デフォルトのプールは次のようになります...

Undertow はバッファー プールを設定します。それ以外の場合はデフォルトが使用され、起動時に警告が表示されます。

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);
        });
    }
}

 ステップ 6: 起動後に成功したかどうかログを確認する


診る: 

-> undo_log データベースで削除されていないデータを確認します。

-> コンソールで rm tm、commit rollback などを確認します。 

-> リモート サービスにエラー レポートを書き込んで、ロールバックが成功したかどうかを確認します。

おすすめ

転載: blog.csdn.net/pingzhuyan/article/details/130801805