SpringCloud Alibaba 統合 Seata

目次

1. Seataサーバー構築

1.seata-serverをダウンロードする

2.seataサーバーを起動します

1. config ディレクトリ内の file.conf を変更します。

2. config ディレクトリ内の registry.conf を変更します。

 3. Mysql は新しいライブラリとテーブルを作成します

4. Seata 構成を初期化する

1. config.txt 構成を変更します。

2. nacos に設定を追加します

5.シータを開始する

2. マイクロサービス統合シート

1. 新しいマイクロサービスを作成し、関連する依存関係を導入します。

1. マイクロサービス pom.xml

2. Seata モジュール pom.xml

2. サブモジュール pom.xml

3. サブモジュールのyml設定

4. データベースを作成する

5. ビジネスモジュール

1. 在庫サービス

2. 注文モジュール

6. テスト検証


1. Seataサーバー構築

1.seata-serverをダウンロードする

ダウンロードするマイクロサービス サポート バージョンの Seata-server バージョンを選択し、必要に応じて Windows または Linux バージョンを選択します。

リリース · セット/セット · GitHub

コンポーネントのバージョン比較表:

ローカルでビルドするために、Windows バージョン 1.3.0 をダウンロードしました。

2.seataサーバーを起動します

実際に使用するには、トランザクションの関連情報をデータベースに保存する必要があり、seata を開始する前に関連する設定を変更する必要があります。

1. config ディレクトリ内の file.conf を変更します。

モードがdbに変更されました

db モジュールはデータベースの URL、ユーザー、パスワードを変更します


## トランザクション ログ ストア、seata-server
ストアでのみ使用されます {   ## ストア モード: ファイル、db、redis   モード = "db"

  ## ファイル ストア プロパティ
  ファイル {     ## ストアの場所 dir dir     = "sessionStore"     # ブランチ セッション サイズ、超過した場合は最初にロックキーの圧縮を試みますが、超過しても例外がスローされます     maxBranchSessionSize = 16384     # グローブ セッション サイズ、超過された場合は例外がスローされます     maxGlobalSessionSize = 512     # fileバッファ サイズ、超過した場合は新しいバッファを割り当てます     fileWriteBufferCacheSize = 16384     # バッチ読み取りサイズを回復するとき     sessionReloadReadSize = 100     # async、sync     flashDiskMode = async   }












  ## データベースストアプロパティ
  db {     ## DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) などの javax.sql.DataSource の実装     datasource = "druid"     ## mysql/oracle/postgresql/h2 /oceanbase など。     dbType = "mysql"     driverClassName = "com.mysql.jdbc.Driver"     url = "jdbc:mysql://101.37.23.0:3306/seata"     ユーザー = "root"     パスワード = "nymi@2023"     minConn = 5     maxConn = 30     globalTable = "global_table"     BranchTable = "branch_table"     lockTable = "lock_table"     queryLimit = 100     maxWait = 5000   }















  ## redis ストア プロパティ
  redis {     ホスト = "127.0.0.1"     ポート = "6379"     パスワード = ""     データベース = "0"     minConn = 1     maxConn = 10     queryLimit = 100   }







}
 

2. config ディレクトリ内の registry.conf を変更します。

この構成は、seata を登録センターに登録するものであり、seata の構成は構成センターに永続化されます。

nacos をレジストリおよび構成センターとして使用します。

タイプを nacos に変更し、nacos の構成をそれぞれ変更する必要があります。

レジストリ {   # ファイル、nacos、eureka、redis、zk、consul、etcd3、ソファ   タイプ = "nacos"

  nacos {     application = "seata-server"     serverAddr = "101.37.23.0:80"     グループ = "SEATA_GROUP"     名前空間 = ""     クラスター = "デフォルト"     ユーザー名 = "nacos"     パスワード = "nacos"   }   eureka {     serviceUrl = "http: //localhost:8761/eureka"     application = "default"     weight = "1"   }   redis {     serverAddr = "localhost:6379"     db = 0     パスワード = ""     クラスター = "デフォルト"     タイムアウト = 0   }   zk {     クラスター = "デフォルト"     serverAddr = "127.0.0.1:2181"     sessionTimeout = 6000
























    connectTimeout = 2000
    ユーザー名 = ""
    パスワード = ""
  }
  consul {     クラスター = "デフォルト"     サーバーアドレス = "127.0.0.1:8500"   }   etcd3 {     クラスター = "デフォルト"     サーバーアドレス = "http://localhost:2379"   }   ソファ {     serverAddr = "127.0.0.1:9603"     アプリケーション = "デフォルト"     リージョン = "DEFAULT_ZONE"     データセンター = "DefaultDataCenter"     クラスター = "デフォルト"     グループ = "SEATA_GROUP"     addressWaitTime = "3000"   }   file {     name = "file.conf"   } }



















config {   # file、nacos、apollo、zk、consul、etcd3   type = "nacos"

  nacos {     serverAddr = "101.37.23.0:80"     namespace = ""     group = "SEATA_GROUP"     username = "nacos"     パスワード = "nacos"   }   consul {     serverAddr = "127.0.0.1:8500"   }   apollo {     appId = "seata-サーバー"     apolloMeta = "http://192.168.1.204:8801"     名前空間 = "アプリケーション"   }   zk {     serverAddr = "127.0.0.1:2181"     sessionTimeout = 6000     connectTimeout = 2000     ユーザー名 = ""     パスワード = ""   }   etcd3 {     serverAddr = "http://localhost:2379"   }
























  ファイル {     名前 = "ファイル.conf"   } }



 

 3. Mysql は新しいライブラリとテーブルを作成します

seataの公式サイトから該当バージョンのソースコードをダウンロードしてください。

 ダウンロードセンター

解凍後、script ディレクトリ全体をコピーし、seata-server 解凍後のフォルダーに置きます。

script/server/db ディレクトリに入り、ステップ 1 で設定した mysql データベース (seata) で mysql.sql スクリプトを実行します (mysql は最初にseata という名前の新しいデータベースを作成する必要があります)。

4. Seata 構成を初期化する

ステップ 3 で script/config-center ディレクトリを開きます。

1. config.txt 構成を変更します。

service.vgroupMapping.guangzhou=default を変更します。広州での構成はプロジェクトのマイクロサービスと一致している必要があります。これについては後続の application.yml で説明します。

store.mode=db を変更します

store.db の背後にあるデータベース関連の構成をいくつか変更します。

2. nacos に設定を追加します

nacos が起動していることを確認してください。

script/config-center/nacos ディレクトリに入ります。

ここで git を開きます (.sh ファイルは Windows で git を使用して実行できます)

以下のコマンドを実行します(IPとポートを実際のものに置き換えてください)

sh nacos-config.sh -h ip -p port -g SEATA_GROUP -t Seata-group

5.シータを開始する

seata/bin ディレクトリに入ります。

Seata-server.bat ファイルをダブルクリックすると、cmd ウィンドウに Seata-server の起動ステータスが表示されます。

起動に成功すると、seata-server サービスが nacos クライアントに登録されたことがわかります。 

2. マイクロサービス統合シート

1. 新しいマイクロサービスを作成し、関連する依存関係を導入します。

1. マイクロサービス pom.xml

<?xml version="1.0"coding="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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <modules> 
        <module>seata</module> 
    </modules> 
    <groupId>com.wind.springcloud</groupId> 
    <artifactId>alibaba</artifactId> 
    <version>0.0。1-SNAPSHOT</version> 
    <name>alibaba</name> 
    <description>springcloudalibaba</description> 
    <packaging>pom</packaging> 
    <properties> 
        <java.version>1.8</java.version>
        <spring.cloud.alibaba.version>2.2.5.RELEASE</spring.cloud.alibaba.version> 
        <spring.boot.version>2.3.11.RELEASE</spring.boot.version> 
        <spring.cloud.version> > Hoxton.SR8</spring.cloud.version> 
    </properties> 

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

        <依存関係> 
            <グループID>org.springframework。boot</groupId> 
            <artifactId>spring-boot-starter-test</artifactId> 
            <scope>test</scope> 
        </dependency> 
    </dependency> 

    <dependencyManagement> 
        <dependency> 
            <!-- alibaba 版本管理--> 
            <dependency> 
                <groupId>com.alibaba.cloud</groupId> 
                <artifactId>spring-cloud-alibaba-dependency</artifactId> 
                <version>${spring.cloud .alibaba.version}</version> 
                <type>pom</type> 
                <scope>import</scope> 
            </dependency> 
            <!-- springboot版本管理--> 
            <dependency> 
                <groupId>org.springframework.boot</groupId> 
                <artifactId>spring-boot-starter-parent</artifactId> 
                <version>${spring.boot.version}</version> 
                <type>pom</type>バージョン}</version> 
                <scope>インポート</scope>
            </dependency> 
            <!-- springcloud版本管理--> 
            <dependency> 
                <groupId>org.springframework.cloud</groupId> 
                <artifactId>spring-cloud-dependency</artifactId> 
                <version>${spring.cloud.version}</version> 
                <type>pom</type> 
                <scope>import</scope> 
            </dependency> 

        </dependency> 
    </dependencyManagement> 

    <build> 
        <plugins> 
            <plugin> 
                <グループID>組織。springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId> 
            </plugin> 
        </plugins> 
    </build> 

</project>

2. Seata モジュール pom.xml

<?xml version="1.0"coding="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> 
        <artifactId>alibaba</artifactId> 
        <groupId>com.wind.springcloud</groupId> 
        <version>0.0.1-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0.0</modelVersion> 

    < groupId>com.wind.springcloud</groupId> 
    <artifactId>seata</artifactId> 
    <version>0.0。1-SNAPSHOT</version> 

    <modules> 
        <module>order-seata</module>
        <module>stock-seata</module> 
        <module>alibaba-order-seata</module> 
        <module>alibaba-stock-seata</module> 
    </modules> 

    <dependency> 
        <dependency> 
            <groupId>org.springframework .boot</groupId> 
            <artifactId>spring-boot-starter-jdbc</artifactId> 
        </dependency> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web< /artifactId> 
        </dependency> 
        <dependency> 
            <groupId>org.mybatis.spring.boot</groupId> 
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version> 
        </dependency> 
        <dependency> 
            <groupId>mysql</groupId> 
            <artifactId>mysql-connector-java</artifactId> 
        </dependency> 
        <dependency> 
            <groupId>com.alibaba </groupId> 
            <artifactId>druid-spring-boot-starter</artifactId> 
            <version>1.2.3</version> 
        </dependency> 
        <!-- nacos服务注册発行现 --> 
        <dependency> 
            <groupId>com .アリババ。cloud</groupId> 
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> 
        </dependency> 
        <!-- 追加openfeign的依赖-->
        <dependency> 
            <groupId>org.springframework.cloud</groupId> 
            <artifactId>spring-cloud-starter-openfeign</artifactId> 
        </dependency> 

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

</project>

2. サブモジュール pom.xml

新しいサブモジュール alibaba-order-seata および alibaba-stock-seata を作成する

ポムは

<?xml version="1.0"coding="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> 
        <artifactId>seata</artifactId> 
        <groupId>com.wind.springcloud</groupId> 
        <version>0.0.1-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0。0</modelVersion> 

    <artifactId>alibaba-order-seata</artifactId> 
    <dependency> 
        <dependency> 
            <groupId>org.projectlombok</groupId> 
            <artifactId>lombok</artifactId>
            <バージョン>1.18.20</バージョン> 
            <スコープ>コンパイル</スコープ> < 
        /依存関係> </
    依存関係> 
    

</プロジェクト>
<?xml version="1.0"coding="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> 
        <artifactId>seata</artifactId> 
        <groupId>com.wind.springcloud</groupId> 
        <version>0.0.1-SNAPSHOT</version> 
    </parent> 
    <modelVersion>4.0。0</modelVersion> 

    <artifactId>alibaba-stock-seata</artifactId> 
    <dependency> 
        <dependency> 
            <groupId>org.projectlombok</groupId> 
            <artifactId>lombok</artifactId>
            <バージョン>1.18.20</バージョン> 
            <スコープ>コンパイル</スコープ> < 
        /依存関係> </
    依存関係> 



</プロジェクト>

3. サブモジュールのyml設定

それらは次のとおりです。上記の広州の構成をエコーし​​ていることがわかります。

サーバー:
  ポート: 8200 
spring:
  アプリケーション:
    名前: 注文
  クラウド: 
    nacos:
      サーバーアドレス: 101.37.23.0:80
      検出:
        ユーザー名: nacos
        パスワード: nacos 
    alibaba: 
      Seata: 
        tx-service-group: 広州
  データソース:
    ユーザー名: root
    パスワード: nymi@2023 
    driver-class-name: com.mysql.jdbc.Driver 
    url: jdbc:mysql://101.37.23.0:3306/seata_order?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai mybatis 
:
  マッパーの場所: クラスパス:/mappers/**/*Mapper.xml
シート:
  レジストリ:
    タイプ: nacos 
    nacos:
      サーバー アドレス: 101.37.23.0:80
      アプリケーション: Seata-server
      ユーザー名: nacos
      パスワード: nacos
      グループ: SEATA_GROUP
  構成:
    タイプ: nacos 
    nacos:
      サーバー アドレス: 101.37.23.0:80
      ユーザー名: nacos
      パスワード: ナコス
      グループ: SEATA_GROUP
サーバー:
  ポート: 8201 

spring:
  アプリケーション:
    名前: ストック
  クラウド: 
    nacos:
      サーバーアドレス: 101.37.23.0:80
      ディスカバリー:
        ユーザー名: nacos
        パスワード: nacos 
    alibaba : 
      Seata: 
        tx-service-group: 広州
  データソース:
    ユーザー名: root
    パスワード: nymi@2023 
    driver-class-name: com.mysql.jdbc.Driver 
    url: jdbc:mysql://101.37.23.0:3306/seata_stock?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai mybatis 
:
  マッパーの場所: クラスパス:/mappers/**/*Mapper.xml
シート:
  レジストリ:
    タイプ: nacos 
    nacos:
      サーバー アドレス: 101.37.23.0:80
      アプリケーション: Seata-server
      ユーザー名: nacos
      パスワード: nacos
      グループ: SEATA_GROUP
  構成:
    タイプ: nacos 
    nacos:
      サーバー アドレス: 101.37.23.0:80
      ユーザー名: nacos
      パスワード: ナコス
      グループ: SEATA_GROUP

4. データベースを作成する

yml設定に対応したデータベースを作成し、

どちらのデータベースも、seata\script\client\at\db で mysql.sql スクリプトを実行します。

5. ビジネスモジュール

1. 在庫サービス

在庫関連のインターフェースを開発する

コアコードは次のとおりです

それぞれ Stock.class

package com.wind.model;

import lombok.Data;

/**
 * @author dongguanghui
 * @date 2023/6/29 14:20
 */
@Data
public class Stock {
    private Integer id;
    private Integer productId;
    private Integer count;
}
StockServiceImpl.クラス
package com.wind.service.impl;

import com.wind.mapper.StockMapper;
import com.wind.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author dongguanghui
 * @date 2023/6/29 14:19
 */
@Service
public class StockServiceImpl implements StockService {

    @Autowired
    StockMapper stockMapper;

    public void reduct(Integer productId) {
        stockMapper.reduct(productId);
        System.out.println("更新商品:"+productId);
    }
}
ストックマッパー.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wind.mapper.StockMapper">

    <update id="reduct">
        update stock set `count` = `count` -1
        where product_id = #{productId}
    </update>
</mapper>

2. 注文モジュール

実装クラスのメソッドにはグローバル トランザクション アノテーションがあり、スタートアップ クラスの設定によりグローバル トランザクション アノテーションが有効になります。

注文モジュールが在庫を呼び出す

メインコード

OrderSeataApplication.class
package com.wind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;

/**
 * @author dongguanghui
 * @date 2023/6/29 14:17
 */
@SpringBootApplication
@EnableFeignClients
@EnableTransactionManagement
public class OrderSeataApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderSeataApplication.class,args);
    }

}
OrderController.class
package com.wind.controller;


import com.wind.model.Order;
import com.wind.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author dongguanghui
 * @date 2023/6/29 11:53
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    OrderService orderService;

    @RequestMapping("/add")
    public String add() {
        Order order = new Order();
        order.setProductId(9);
        order.setStatus(0);
        order.setTotalAmount(100);

        orderService.create(order);
        return "下单成功";
    }
}
OrderServiceImpl.class
package com.wind.service.impl;


import com.wind.api.StockService;
import com.wind.mapper.OrderMapper;
import com.wind.model.Order;
import com.wind.service.OrderService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * @author dongguanghui
 * @date 2023/6/29 14:19
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    StockService stockService;

    @GlobalTransactional
    public Order create(Order order) {
        // 插入订单
        orderMapper.insert(order);

        // 扣减库存
        stockService.reduct(order.getProductId());
        int a=1/0;
        return order;
    }
}
オーダー.クラス
package com.wind.model;

import lombok.Data;

/**
 * @author dongguanghui
 * @date 2023/6/29 14:20
 */
@Data
public class Order {
    private Integer id;
    private Integer productId;
    private Integer status;
    private Integer totalAmount;
}
StockService.クラス
package com.wind.api;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @author dongguanghui
 * @date 2023/6/29 17:26
 */
@FeignClient(value = "stock",path = "/stock")
public interface StockService {

    @RequestMapping("/reduct")
    public String reduct(@RequestParam("productId") Integer productId);
}
オーダーマッパー.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wind.mapper.OrderMapper">

    <insert id="insert" parameterType="com.wind.model.Order">
        insert into `order` (product_id,`status`,total_amount)
        values
        (#{productId},#{status},#{totalAmount})
    </insert>
</mapper>

6. テスト検証

int a=1/0; ブレークポイント。

これが実行されると、データベースはデータを変更し、undo_log テーブルには元のデータと変更されたデータのログが保存されます。

コードの次の行を引き続き実行し、エラーを報告します。

この時点で、トランザクションはロールバックされ、ロールバック後に undo_log データはクリアされます。

int a=1/0 の場合、int a=1 に変更します。

その後、この行までのコードの実行は前と同じになります。

通常どおり、次の行に進みます。

この時点で、トランザクションをコミットし、undo_log データをクリアします。

これまでに分散トランザクション環境が構築されてきました。

おすすめ

転載: blog.csdn.net/Spring_possible/article/details/131516693