SpringCloud は Seata を統合して分散トランザクションを解決します (ビルド + ソースコード)

SpringCloud は Seata を統合して分散トランザクションを解決します (ビルド + ソースコード)

[[356529]]

シータ公式サイト: http://seata.io/zh-cn/

序文

マイクロサービス アーキテクチャが非常に普及しているため、新世代のマイクロサービス ソリューションである Spring Cloud Alibaba が提供するオープン ソースの分散トランザクション ソリューション フレームワークである Seata が、分散トランザクションを解決するための第一の選択肢となっていることは間違いありません。前回の 2 つの記事では、一般的な分散ソリューションと成熟したフレームワークを紹介し、Seata の概念についても紹介しました。分散トランザクション処理を経験したことのない方は、まず概要をご覧ください。

  • SpringCloud Alibaba マイクロサービス アーキテクチャ (XI) - 共通分散トランザクション ソリューションと理論的基礎
  • SpringCloud Alibaba マイクロサービス アーキテクチャ (XII) - 分散トランザクション ソリューション フレームワークの Seata コンセプトの紹介

したがって、この記事で Seata を Spring Cloud と統合する前に、Spring Cloud Alibaba と Spring Boot と Spring Cloud 間のバージョン対応を理解しておく必要があります。

バージョン選択: Spring Cloud Alibaba と Spring Boot および Spring Cloud のバージョン間の対応

1. バージョン要件

落とし穴 1: プロジェクトで druid データベース接続プールが使用され、SpringBoot Starter 依存関係 druid-spring-boot-starter が導入されている場合、seata ソース コードで導入された druid 依存関係が druid-spring-boot-starter の自動アセンブリ クラスと競合するため、druid-spring-boot-starter 依存関係を druid1.1.23 に置き換える必要があります。競合が発生した場合、プロジェクトの起動時に次のような例外が発生します。

2. Seata環境設定を統合する

1. seata-server-1.2.0とseata-1.2.0のソースコードをダウンロードする

seate-server ダウンロード: https://seata.io/zh-cn/blog/download.html、使用する必要がある seata1.2 圧縮パッケージをダウンロードします。

seata-1.2.0 ソースコードのダウンロード: https://github.com/seata/seata/releases

ここに画像の説明を挿入

2. undo_logログテーブルを作成する

seata1.2 ソース コードの seata-1.2.0\script\client\at\db ディレクトリには、mysql、oracle、postgresql の 3 つのデータベースの undo-log リバース ログ ロールバック テーブルを生成するためのテーブル作成スクリプトがあります。

  • プロジェクトのグローバル トランザクションに参加しているデータベースに undo_log テーブルを追加します。 undo_log テーブル スクリプトは、データベースの種類に応じて選択されます。
  1. -- AT モードの場合、ビジネス データベース用にこの SQL を初期化する必要があります。 seata サーバーではそれは必要ありません。  
  2. 作成する テーブルが存在しない場合`undo_log`
  3. `branch_id` BIGINT (20) NOT   NULL COMMENT 'ブランチトランザクションID'
  4. `xid` VARCHAR (100)ではない  NULL COMMENT 'グローバルトランザクションID'
  5. `context` VARCHAR (128) NOT   NULL COMMENT 'undo_logコンテキスト(シリアル化など)'
  6. `rollback_info` LONGBLOB NOT   NULLコメント「ロールバック情報」
  7. `log_status` INT (11) NOT   NULL COMMENT '0:通常状態、1:防御状態'
  8. `log_created` DATETIME(6) NOT   NULLコメント'create datetime'
  9. `log_modified` DATETIME(6) NOT   NULLコメント'datetimeの変更'
  10. 個性的 キー`ux_undo_log` (`xid`, `branch_id`)
  11. ) エンジン = InnoDB
  12. AUTO_INCREMENT = 1
  13. デフォルト文字セット = utf8 コメント = 'AT トランザクション モード undo テーブル' ;

3. seataトランザクション関連テーブルを作成する

Seata1.2 のソースコードをダウンロードし、上記のように解凍します。現在、mysql、oracle、postgresql の 3 つのデータベースをサポートしています。上記の 3 つのスクリプトは、Seata のサーバー側で分散トランザクションを調整および処理するために必要な 3 つのテーブル用です。さまざまなデータベース用の global_table、branch_table、および lock_table 作成スクリプトを提供します。独自のデータベースに応じて、対応する SQL スクリプトを実行できます。

ここでは MySQL を例に挙げます。 MySQL データベースに seata という名前のライブラリを作成し、次の SQL を実行して 3 つのテーブルを生成します。

  1. ---------------------------------- storeMode が 'db' の場合に使用されるスクリプト --------------------------------  
  2. -- GlobalSessionデータを保存するテーブル 
  3. 作成する テーブルが存在しない場合`global_table`
  4. `xid` VARCHAR (128)ではない  NULL
  5. `transaction_id` BIGINT
  6. `status` TINYINT NOT   NULL
  7. `application_id` VARCHAR (32)、
  8. `transaction_service_group` VARCHAR (32)、
  9. `トランザクション名` VARCHAR (128)、
  10. `タイムアウト` INT ,
  11. `begin_time` BIGINT
  12. `application_data` VARCHAR (2000)、
  13. `gmt_create` 日付時刻、
  14. `gmt_modified` 日付時刻、
  15. 主要な キー(`xid`)、
  16. キー`idx_gmt_modified_status` (`gmt​​_modified`, `status`),
  17. キー`idx_transaction_id` (`transaction_id`)
  18. ) エンジン = InnoDB
  19. デフォルト文字セット = utf8;
  20.  
  21. -- BranchSessionデータを保存するテーブル 
  22. 作成する テーブルが存在しない場合`branch_table`
  23. `branch_id` BIGINT        ない  NULL
  24. `xid` VARCHAR (128)ではない  NULL
  25. `transaction_id` BIGINT
  26. `resource_group_id` VARCHAR (32)、
  27. `resource_id` VARCHAR (256)、
  28. `branch_type` VARCHAR (8)、
  29. `ステータス` TINYINT、
  30. `client_id` VARCHAR (64)、
  31. `application_data` VARCHAR (2000)、
  32. `gmt_create` 日付時刻(6)、
  33. `gmt_modified` 日付時刻(6)、
  34. 主要な キー(`branch_id`)、
  35. キー`idx_xid` (`xid`)
  36. ) エンジン = InnoDB
  37. デフォルト文字セット = utf8;
  38.  
  39. -- ロックデータを保存するテーブル 
  40. 作成する テーブルが存在しない場合`lock_table`
  41. `row_key` VARCHAR (128) NOT   NULL
  42. `xid` VARCHAR (96)、
  43. `transaction_id` BIGINT
  44. `branch_id` BIGINT        ない  NULL
  45. `resource_id` VARCHAR (256)、
  46. `テーブル名` VARCHAR (32)、
  47. `pk` VARCHAR (36)、
  48. `gmt_create` 日付時刻、
  49. `gmt_modified` 日付時刻、
  50. 主要な キー(`行キー`)、
  51. キー`idx_branch_id` (`branch_id`)
  52. ) エンジン = InnoDB
  53. デフォルト文字セット = utf8;

4. プロジェクトに seata 依存関係を導入する

4.1 マイクロサービスがSpringCloudの場合

  1. <! -- 分散トランザクション seata パッケージ -->  
  2. <! --seata 開始-->  
  3. <依存関係>
  4. <グループ ID>com.alibaba.cloud</グループ ID>
  5. <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
  6. <バージョン>2.1.3.RELEASE</バージョン>
  7. <除外事項>
  8. <除外>
  9. <groupId>io.seata</groupId>
  10. <artifactId>seata-spring-boot-starter</artifactId>
  11. </除外>
  12. </除外>
  13. </依存関係>
  14. <依存関係>
  15. <groupId>io.seata</groupId>
  16. <artifactId>seata-spring-boot-starter</artifactId>
  17. <バージョン>1.2.0</バージョン>
  18. </依存関係>
  19. <! --seata終了-->  

4.2 マイクロサービスがDubboの場合

  1. <依存関係>
  2. <groupId>io.seata</groupId>
  3. <artifactId>seata-spring-boot-starter</artifactId>
  4. <バージョン>1.2.0</バージョン>
  5. </依存関係>

5. seata-serverのregistry.confを変更する

registry.conf 登録センターを nacos として設定し、nacos 関連の属性パラメータを設定します。

  1. ## seata-server、サポートファイル、nacos、eureka、redis、zk、consul、etcd3、sofa の登録センターを設定します。
  2. レジストリ {
  3. # ファイル、nacos、eureka、redis、zk、consul、etcd3、sofa
  4. タイプ = "ナコス"  
  5.  
  6. ナコス
  7. アプリケーション = "seata-server"  
  8. サーバーアドレス = "127.0.0.1:8848"  
  9. グループ= "SEATA_GROUP"  
  10. 名前空間 = "public"  
  11. ユーザー名 = "nacos"  
  12. クラスター = "デフォルト"  
  13. パスワード= "nacos"  
  14. }
  15.    
  16. ファイル {
  17. 名前= "file.conf"  
  18. }
  19. }
  20.  
  21. ## seata-server、サポートファイル、nacos、apollo、zk、consul、etcd3 の設定センターを設定します
  22. 設定{
  23. # ファイル、nacos、apollo、zk、consul、etcd3
  24. タイプ = "ナコス"  
  25.  
  26. ナコス
  27. サーバーアドレス = "127.0.0.1:8848"  
  28. 名前空間 = "public"  
  29. グループ= "SEATA_GROUP"  
  30. ユーザー名 = "nacos"  
  31. パスワード= "nacos"  
  32. }
  33.   
  34. ファイル {
  35. 名前= "file.conf"  
  36. }
  37. }

6. seata-serverのfile.configを変更する

file.config の DB モード関連のパラメータを設定します。

  1. ## ローカル ドキュメントとデータベースをサポートするように seata-server のデータ保存方法を構成します。
  2. ##トランザクションログ ストア。seata -serverのみ使用されます
  3. 店 {
  4. ## 保存モード: ファイル、DB、Redis
  5. モード = "db"  
  6.  
  7. ## ファイルストアプロパティ
  8. ファイル {
  9. ##保存場所のディレクトリ
  10. dir = "セッションストア"  
  11. # セッションサイズを分岐します。超過した場合はまずロックキーの圧縮を試みます。それでも超過した場合は例外がスローされます。
  12. 最大ブランチセッションサイズ = 16384
  13. # globe セッションサイズ。超過すると例外がスローされます
  14. 最大グローバルセッションサイズ = 512
  15. # ファイルバッファサイズ、超過した場合は新しいバッファを割り当てます
  16. ファイル書き込みバッファキャッシュサイズ = 16384
  17. #バッチ読み取りを回復するとき サイズ 
  18. セッションリロード読み取りサイズ = 100
  19. # 非同期、同期
  20. フラッシュディスクモード = 非同期
  21. }
  22.  
  23. ##データベースストアプロパティ
  24. デシベル{
  25. ## DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari)などjavax.sql.DataSource実装。
  26. データソース = "ドルイド"  
  27. ## mysql/oracle/postgresql/h2/oceanbase など
  28. dbType = "mysql"  
  29. ドライバークラス名 = "com.mysql.jdbc.Driver"  
  30. url = "jdbc:mysql://127.0.0.1:3306/seata"  
  31. ユーザー= "root"  
  32. パスワード= "root"  
  33. 最小接続数 = 5
  34. 最大接続数 = 30
  35. グローバルテーブル = "グローバルテーブル"  
  36. branchTable = "ブランチテーブル"  
  37. lockTable = "ロックテーブル"  
  38. クエリ制限 = 100
  39. 最大待機時間 = 5000
  40. }
  41.  
  42. ## redis ストアプロパティ
  43. レディス{
  44. ホスト = "127.0.0.1"  
  45. ポート = "6379"  
  46. パスワード= ""  
  47. データベース= "0"  
  48. 最小接続 = 1
  49. 最大接続数 = 10
  50. クエリ制限 = 100
  51. }
  52. }

7. nacosスクリプトを修正してnacosコンソールに送信する

ダウンロードした nacos を実行し、https://github.com/seata/seata/tree/develop/script/config-center の config.txt ファイルを参照して変更します。

  1. service.vgroupMapping.my_test_tx_group=デフォルト 
  2. ストアモード=db
  3. store.db.datasource=ドルイド
  4. ストア.db.dbType=mysql
  5. store.db.driverClassName=com.mysql.jdbc.Driver
  6. store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode= true  
  7. store.db.user = ユーザー名
  8. store.db.password =パスワード 
  9. ストア.db.minConn=5
  10. ストア.db.maxConn=30
  11. store.db.globalTable=グローバルテーブル
  12. store.db.branchTable=ブランチテーブル
  13. ストア.db.クエリ制限=100
  14. store.db.lockTable=ロックテーブル
  15. ストア.db.maxWait=5000

リポジトリ https://github.com/seata/seata/tree/develop/script/config-center/nacos で提供されている nacos スクリプト nacos-config.sh を実行し、上記の情報を nacos コンソールに送信します。パラメータを変更する必要がある場合は、nacos コンソールにログインして直接変更できます。

操作は以下のとおりです。


8. application.yml の設定

公式 github リポジトリ (https://github.com/seata/seata/tree/develop/script/client) から参照構成を取得し、変更して、プロジェクトの application.yml ファイルに追加します。

  1. #Seata 分散トランザクション構成 ( ATモード)
  2. シータ:
  3. 有効: true  
  4. アプリケーションID : ${spring.application.name }
  5. #クライアントとサーバーは同じトランザクショングループに属しています
  6. tx-サービス-グループ: my_test_tx_group
  7. 自動データソースプロキシを有効にする: true  
  8. サービス:
  9. vgroup マッピング:
  10. my_test_tx_group:デフォルト 
  11. 設定:
  12. タイプ: ナコス
  13. ナコス:
  14. 名前空間: "public"  
  15. サーバーアドレス: 127.0.0.1:8848
  16. グループ: SEATA_GROUP
  17. ユーザー名: "nacos"  
  18. パスワード 「nacos」  
  19. #nacosへのサービス登録
  20. レジストリ:
  21. タイプ: ナコス
  22. ナコス:
  23. アプリケーション: seata-server
  24. サーバーアドレス: 127.0.0.1:8848
  25. グループ: SEATA_GROUP
  26. 名前空間: "public"  
  27. ユーザー名: "nacos"  
  28. パスワード 「nacos」  
  29. クラスター:デフォルト 

9. seata-serverを実行する

seata-server を起動して実行します。成功したら、独自のサービスプロバイダーとサービス参加者を実行します。グローバル トランザクション呼び出し元 (グローバル トランザクションを開始するサービス) のインターフェースに @GlobalTransactional アノテーションを追加します。

これまでに、SpringCloud 統合、seata1.2 統合、nacos の seata1.2 統合の構成と登録センターが完全に統合されました。

3. プロジェクトの準備

前の手順で Seata 環境を完了している場合は、プロジェクトを開始することができます。コンソールに異常がなければ構築は成功です。

次に、タイトルとして Seata の公式ドキュメントの典型的な例を使用し、ユーザーが注文を出し、注文を作成し、同時に在庫数量を減算することによって発生する分散トランザクションの問題をシミュレートし、Seata の次の機能を使用してそれを解決します。

1. 注文サービス

  • オーダーコントローラー
  1. /**
  2. * @desc : 注文サービス
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:27
  5. */
  6. @レストコントローラ
  7. 翻訳者
  8. @RequestMapping( "/order" )
  9. パブリッククラスOrderController{
  10.  
  11. オートワイヤード
  12. プライベート OrderServiceImpl orderService;
  13.  
  14. /**
  15. * ユーザーが購入して注文し、グローバルトランザクションの送信をシミュレートします
  16. * @param pid
  17. * @戻る 
  18. */
  19. @RequestMapping( "/purchase/commit/{pid}" )
  20. 公共 注文orderCommit(@PathVariable( "pid" ) Integer pid) {
  21. orderService.createOrderCommit(pid)を返します
  22. }
  23.  
  24. /**
  25. * ユーザーが購入して注文し、グローバルトランザクションのロールバックをシミュレートします。
  26. * @param pid
  27. * @戻る 
  28. */
  29. @RequestMapping( "/purchase/rollback/{pid}" )
  30. 公共 オーダーorderRollback(@PathVariable( "pid" ) Integer pid) {
  31. orderService.createOrderRollback(pid)を返します
  32. }
  33.  
  34. }
  • 注文サービスの実装
  1. /**
  2. * @説明:
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:30
  5. */
  6. @サービス
  7. 翻訳者
  8. パブリッククラス OrderServiceImpl {
  9. オートワイヤード
  10. プライベート OrderDao orderDao;
  11.  
  12. オートワイヤード
  13. プライベートProductService productService;
  14.  
  15. // ユーザーは注文を出し、グローバルトランザクションの送信をシミュレートします
  16. 公共 注文createOrderCommit(整数pid) {
  17. log.info( "製品番号 {} の注文リクエストを受け取り、製品マイクロサービスを呼び出して製品情報を照会しました" 、 pid);
  18.  
  19. //1 製品マイクロサービスを呼び出して製品情報を照会する
  20. 製品 product = productService.findByPid(pid);
  21. log.info( "製品番号 {} の情報が見つかりました。内容は次のとおりです: {}" , pid, JSON.toJSONString(product));
  22.  
  23. //2 注文する(注文を作成する)
  24. 注文  order = 新しい注文();
  25. オーダー.setUid(1);
  26. .setUsername ( "テストユーザー" );
  27. 命令.setPid(pid);
  28. 注文.setPname(product.getPname());
  29. 注文.setPprice(product.getPprice());
  30. 順序.setNumber (1);
  31. orderDao.save(注文);
  32. log.info( "注文が正常に作成されました。注文情報は {} です" , JSON.toJSONString( order ));
  33.  
  34. //3 在庫を減算するm
  35. productService.reduceInventoryCommit(pid、 order.getNumber ());
  36.  
  37. 戻る 注文;
  38. }
  39.  
  40. // ユーザーは注文を出し、グローバルトランザクションのロールバックをシミュレートします
  41. @GlobalTransactional //グローバルトランザクション制御
  42. 公共 注文createOrderRollback(整数pid) {
  43. log.info( "製品番号 {} の注文リクエストを受け取り、製品マイクロサービスを呼び出して製品情報を照会しました" 、 pid);
  44.  
  45. //1 製品マイクロサービスを呼び出して製品情報を照会する
  46. 製品 product = productService.findByPid(pid);
  47. log.info( "製品番号 {} の情報が見つかりました。内容は次のとおりです: {}" , pid, JSON.toJSONString(product));
  48.  
  49. //2 注文する(注文を作成する)
  50. 注文  order = 新しいOrder ();
  51. オーダー.setUid(1);
  52. .setUsername ( "テストユーザー" );
  53. 命令.setPid(pid);
  54. 注文.setPname(product.getPname());
  55. 注文.setPprice(product.getPprice());
  56. 順序.setNumber (1);
  57. orderDao.save(注文);
  58. log.info( "注文が正常に作成されました。注文情報は {} です" , JSON.toJSONString( order ));
  59.  
  60. //3 在庫を減算するm
  61. productService.reduceInventoryRollback(pid、 order.getNumber ());
  62.  
  63. 戻る 注文;
  64. }
  65.  
  66. }
  • 製品サービス用のFeignクラスProductService
  1. /**
  2. * @説明:
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:43
  5. */
  6. @FeignClient(値 = "product-service" 、構成 = FeignRequestInterceptor.class)
  7. パブリックインターフェースProductService {
  8. //@FeignClient 値 + @RequestMapping 値は、実際には完了したリクエスト アドレス"http://product-service/product/" + pid です
  9. //リクエストのURI部分を指定する
  10. @RequestMapping( "/product/product/{pid}" )
  11. Product findByPid(@PathVariable Integer pid);
  12.  
  13. //在庫を減算し、グローバルトランザクションの送信をシミュレートする
  14. //パラメータ 1: 製品 ID
  15. //パラメータ2: 控除量
  16. @RequestMapping( "/product/reduceInventory/commit" )
  17. void ReduceInventoryCommit(@RequestParam( "pid" )整数pid、
  18. @RequestParam( "number" )整数値);
  19.  
  20. //在庫を減算し、グローバルトランザクションのロールバックをシミュレートします
  21. //パラメータ 1: 製品 ID
  22. //パラメータ2: 控除量
  23. @RequestMapping( "/product/reduceInventory/rollback" )
  24. void ReduceInventoryRollback(@RequestParam( "pid" )整数pid,
  25. @RequestParam( "number" )整数値);
  26.  
  27. }

2. 製品サービス

  • 製品コントローラー
  1. /**
  2. * @説明:
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:16
  5. */
  6. @レストコントローラ
  7. 翻訳者
  8. @RequestMapping( "/product" )
  9. パブリッククラスProductController {
  10.  
  11. オートワイヤード
  12. プライベートProductService productService;
  13.  
  14. /**
  15. * 在庫を減算、通常->グローバルトランザクション送信をシミュレート
  16. * @param pid
  17. * @パラメータ番号
  18. */
  19. @RequestMapping( "/reduceInventory/commit" )
  20. パブリックvoid ReduceInventoryCommit(整数pid,整数数) {
  21. 文字列トークン = ServletUtils.getRequest().getHeader( "token" );
  22. log.info( "ヘッドリクエストヘッダーから渡された値はトークンです: " + トークン);
  23. productService.reduceInventoryCommit(pid、数値);
  24. }
  25.  
  26. /**
  27. * 在庫を減算、例外 -> グローバルトランザクションのロールバックをシミュレート
  28. * @param pid
  29. * @パラメータ番号
  30. */
  31. @RequestMapping( "/reduceInventory/rollback" )
  32. パブリックvoid ReduceInventoryRollback(整数pid,整数数) {
  33. productService.reduceInventoryRollback(pid、数値);
  34. }
  35.  
  36. //製品情報のクエリ
  37. @RequestMapping( "/product/{pid}" )
  38. public Product product(@PathVariable( "pid" ) Integer pid) {
  39. log.info( "次に、製品番号 {} の情報を照会します" , pid);
  40. 製品 product = productService.findByPid(pid);
  41. log.info( "製品情報のクエリが成功しました。コンテンツは {} です" 、 JSON.toJSONString(product));
  42. 商品を返品する
  43. }
  44. }
  • ProductService インターフェース クラス
  1. /**
  2. * @desc : 製品インターフェース
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:18
  5. */
  6. パブリックインターフェースProductService {
  7. //PIDに基づいて製品情報を照会する
  8. 製品 findByPid(整数pid);
  9.  
  10. //在庫を減算、通常->グローバルトランザクションの送信をシミュレート
  11. void ReduceInventoryCommit(整数pid、整数数);
  12.  
  13. //在庫を減算、例外->グローバルトランザクションのロールバックをシミュレート
  14. void ReduceInventoryRollback(整数pid、整数数);
  15. }
  • ProductServiceImpl インターフェース実装クラス
  1. /**
  2. * @desc : 製品サービス実装クラス
  3. * @著者: cao_wencao
  4. * @日付: 2020-09-22 23:20
  5. */
  6. @サービス
  7. パブリッククラス ProductServiceImpl は ProductService を実装します {
  8.  
  9. オートワイヤード
  10. プライベート ProductDao productDao;
  11.  
  12. @オーバーライド
  13. パブリック製品findByPid(整数pid) {
  14. productDao.findById(pid).get()を返します
  15. }
  16.  
  17. /**
  18. * 在庫を減算、通常->グローバルトランザクション送信をシミュレート
  19. * @param pid
  20. * @パラメータ番号
  21. */
  22. @オーバーライド
  23. パブリックvoid ReduceInventoryCommit(整数pid,整数数) {
  24. //クエリ
  25. 製品 product = productDao.findById(pid).get();
  26. //検証を省略
  27.  
  28. //メモリ内の推論
  29. product.setStock(product.getStock() - 数値);
  30.  
  31. //控除インベントリを保存する
  32. productDao.save(製品);
  33. }
  34.  
  35. /**
  36. * 在庫を減算、例外 -> グローバルトランザクションのロールバックをシミュレート
  37. * @param pid
  38. * @パラメータ番号
  39. */
  40. @Transactional(rollbackFor = Exception.class) //サービスプロバイダーのローカルトランザクション注釈
  41. @オーバーライド
  42. パブリックvoid ReduceInventoryRollback(整数pid,整数数) {
  43. //クエリ
  44. 製品 product = productDao.findById(pid).get();
  45. //検証を省略
  46.  
  47. //メモリ内の推論
  48. product.setStock(product.getStock() - 数値);
  49.  
  50. //例外をシミュレートする
  51. 整数i = 1 / 0;
  52.  
  53. //控除インベントリを保存する
  54. productDao.save(製品);
  55. }
  56. }

IV.参考資料

シータ公式サイト:

  • http://seata.io/zh-cn/

Seata FAQ:

  • http://seata.io/zh-cn/docs/overview/faq.html

Seata 統合 1.2 チュートリアル:

  • https://www.bilibili.com/video/BV12Q4y1A7Nt

アップグレード 1.3 チュートリアル:

  • https://www.bilibili.com/video/BV1Cf4y1X7vR
  • https://mp.weixin.qq.com/s/2KSidJ72YsovpJ94P1aK1g

Springcloud 統合デモ:

  • https://gitee.com/itCjb/spring-cloud-alibaba-seata-demo

5. 完全なソースコード

  • https://github.com/Thinkingcao/SpringCloudLearning/tree/master/springcloud-seata

<<:  2020年、クラウドコンピューティングが新たな戦場を開く

>>:  SaaS 企業はどこまで行けるでしょうか?主にこの2つの指標によって決まる

推薦する

オリジナルコンテンツ、強力なマーケティング、ユーザー重視、より良い結果

今はイノベーションが奨励される時代ですが、独創性を生み出す土壌がありません。彼らの多くは法的意識が弱...

何もすることがないので、ASO最適化のための8つの戦略を紹介します

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますASOはど...

モバイルエッジコンピューティングのセキュリティリスク分析とソリューション

ラボガイドモバイル エッジ コンピューティングは、エッジ ノードにクラウド コンピューティング機能を...

K8s の交換が必要です!

著者 |趙雲現在、Kubernetes はマイクロサービスのデプロイメント問題を解決し、すでにコンテ...

シーメンスはRed Hat OpenShiftで工場エッジのイノベーションを加速

オープンソース ソリューションの世界的な大手プロバイダーである Red Hat は本日、シーメンスが...

関連リンクの比率とリンク幅についての簡単な説明

私は SEO の知識に関連する記事をたくさん読んできました。リンクの関連性が非常に重要だと言う人もい...

iPaaS - ハイブリッドおよびマルチクラウド向けミドルウェア

新しいタイプのクラウド サービス モデルである統合プラットフォーム (iPaaS) は、さまざまなサ...

ネガティブなケーススタディ:Baidu の低品質コンテンツの扱い

7月2日、百度はコミュニティプラットフォームで6月22日と6月28日の事件に対する回答を発表しました...

crowncloud-Phoenix KVM 再入荷/7 USD/2G メモリ/30g ハードディスク/3T トラフィック

crowncloudのPhoenix KVMが再入荷し始めました。新モデルのはずです。今回は、2Gメ...

Google は毎日 41,000 件の海賊版と疑われるリンクを削除し、そのプロセスを 11 時間で完了しています

5月25日、海外メディアの報道によると、グーグルは著作権者から、検索結果が海賊版コンテンツを指し示し...

フロントエンド検索のユーザーをターゲットにしたオンラインアライアンスの広告配置戦略について簡単に説明します。

長い間記事を書いていませんでした。今日は、オンラインアライアンスの広告戦略と、オンラインアライアンス...

今年422のポルノサイトが捜査され処罰されたが、次回の取り締まりはさらに厳しくなるだろう

国家ポルノ及び違法出版物取締局、中国サイバースペース管理局、工業情報化部、公安部など4つの部門は4月...

アプリの運用とプロモーションのための 3 つのチャネル: オンライン、オフライン、新しいメディア。

アプリの運用は簡単ではなく、製品の品質、プロモーション チャネル、戦略に依存します。アプリの運用とプ...

Baiduのいいねボタンは、Baidu Shareを追加してから24時間以内に表示されます。

Baidu の「いいね!」ボタンは小規模なテストではありません。百度の「いいね!」ボタンは小規模なテ...