目次
1. config ディレクトリ内の file.conf を変更します。
2. config ディレクトリ内の registry.conf を変更します。
1. 新しいマイクロサービスを作成し、関連する依存関係を導入します。
1. Seataサーバー構築
1.seata-serverをダウンロードする
ダウンロードするマイクロサービス サポート バージョンの Seata-server バージョンを選択し、必要に応じて Windows または Linux バージョンを選択します。
コンポーネントのバージョン比較表:
ローカルでビルドするために、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 データをクリアします。
これまでに分散トランザクション環境が構築されてきました。