SpringBoot +ダボ+ Seata分散トランザクション戦闘!

序文

Seata アリババはマイクロサービスシナリオの下で分散トランザクションが直面している問題を解決するために、効率的かつビジネス0侵襲的な方法で、トランザクションミドルウェア、オープンソースを配布されています。

実際には、関係者はGitHub、環境の様々な環境下で与えられたSeata:アプリケーションのサンプルプロジェクト、アドレスhttps://github.com/seata/seata-samples

なぜ私は2つの主な理由のために、再びそれを再書きたいん:

  • 公式サイトのコード例では、にどのような役割として、あまりにも多くの混乱を頼ります

  • Seata以下の関連情報、建物の過程で著者は、いくつかのピットが発生し、それを記録

まず、環境を準備

この記事では、ソフトウェア環境に関連する次のとおりです。

  • SpringBoot 2.1.6.RELEASE

  • ダボ2.7.1

  • MyBatisの3.5.1

  • 0.6.1シート

  • 飼育係3.4.10

1、ビジネスシーン

プロセスを簡略化するために、我々は2つのだけ注文や在庫のサービスを必要とします。オーダーを作成する場合は、サービスの在庫、在庫控除を呼び出します。

次のような設計に関与テーブル:

CREATE TABLEの`t_order`(    
` id`はint(11)NOT NULL AUTO_INCREMENT、    
`order_no`のVARCHAR(255)のDEFAULT NULL、   
 ` user_id`のVARCHAR(255)のDEFAULT NULL、   
  `commodity_code`のVARCHAR(255)のDEFAULT NULL、    
  ` count` INT(11)DEFAULT '0'、   
   'amount`ダブル(14,2)DEFAULT '0.00'、   
    PRIMARY KEY( `id`))ENGINE = InnoDBのAUTO_INCREMENT = 38 DEFAULT CHARSET = UTF8。 
    CREATE TABLEの`t_storage`(` id`はint(11)NOT NULL AUTO_INCREMENT、   
     `commodity_code`のVARCHAR(255)のDEFAULT NULL、    
     ` name`ののVARCHAR(255)のDEFAULT NULL、    
     `count` int型(11)DEFAULT '0'、    
     PRIMARY KEY( `id`)     
     UNIQUE KEY` commodity_code`( `commodity_code`)) 
     ENGINE = InnoDBのAUTO_INCREMENT = 2 DEFAULT CHARSET = UTF8。

また、ロールバック・ログ表を必要とします。

CREATE TABLEを`undo_log`(    
` id` BIGINT(20)NOT NULL AUTO_INCREMENT、    
`branch_id` BIGINT(20)NOT NULL、    
` xid`のVARCHAR(100)NOT NULL、    
`rollback_info` LONGBLOB NULL NOT、    
` log_status`整数(11 )NOT NULL、    
`log_created`日時NULL NOT、   
 ` log_modified`日時NULL NOT、    
 `ext`のVARCHAR(100)は、デフォルトのNULL、    
 ` context`のVARCHAR(100)は、デフォルトのNULL、   
  PRIMARY KEY( `id`)、    
  UNIQUE KEY` ux_undo_log ( `` xid`、 `branch_id`))ENGINE = InnoDBのAUTO_INCREMENT = 67デフォルトの文字セット= UTF8。

2、Seataはダウンロードしてインストール

オープンhttps://github.com/seata/seata/releases、最新バージョンですv0.6.1

解凍をダウンロードした後seata-server-0.6.1\distribution\bin、あなたが見ることができるディレクトリseata-server.bat和seata-server.sh、ダブルクリックの実行を選択します。

あなたが見たときに驚くことではないが、その後、-Server started ...他の言葉を、それが正常に起動しました。

図3は、Mavenは依存しています

このプロジェクトは、ダボ、ダボをですので、我々は最初にその依存関係を導入しました。

<依存性> <のgroupId> org.apache.dubbo </のgroupId> <たartifactId>ダボ</たartifactId> <バージョン> 2.7.1 </バージョン> </依存> <依存性> <のgroupId> org.apache.dubbo </ groupId> <たartifactId>ダボスプリングブート・スターター</たartifactId> <バージョン> 2.7.1 </バージョン> </依存関係>复制代码

ダボサービスは、飼育係に導入学芸員のクライアントを登録します。

<依存性> <のgroupId> org.apache.curator </のgroupId> <たartifactId>キュレーターフレームワーク</たartifactId> <バージョン> 2.13.0 </バージョン> </依存> <依存性> <のgroupId> org.apache.curator </のgroupId> <たartifactId>キュレーター-レシピ</たartifactId> <バージョン> 2.13.0 </バージョン> </依存>复制代码

最後に、Seataの導入。

<依存性> <のgroupId> io.seata </のgroupId> <たartifactId> seataオール</たartifactId> <バージョン> 0.6.1 </バージョン> </依存>

もちろん、そのような他のあるMybatis、mysql-connector非粘着のような、それが自己紹介することができます。

第二に、プロジェクト構成

1、application.properties

ここだけ、あなたはダボに関連するデータベース接続情報および情報を設定する必要があります。

server.port = 8011 spring.datasource.url = JDBCます。mysql://127.0.0.1:3306 / seata spring.datasource.username =ルートspring.datasource.password =ルートdubbo.application.name =オーダーサービスdubbo.registry .address =飼育係://127.0.0.1:2181 dubbo.protocol.name =ダボdubbo.protocol.port = 20881 dubbo.consumer.timeout = 9999999 dubbo.consumer.check =偽

図2に示すように、データ・ソース

Seataトランザクションブランチは、プロキシデータソースによって達成されるので、あなたはそれ以外の場合は、トランザクションがロールバックされません、プロキシデータソースを設定する必要があります。

@Bean公共DataSourceProxy dataSourceProxy(データソースのdataSource){新しいDataSourceProxy(データソース)を返します。}

どこ、ということに注意してくださいDataSourceProxyクラスが配置されているio.seata.rm.datasourceパッケージ内。

3、Seata設定

また、あなたは、グローバル・トランザクションのスキャナを設定する必要があります。二つのパラメータがありますが、一つは、アプリケーション名でグループ取引です。

@Bean公共GlobalTransactionScanner globalTransactionScanner(){戻り新しいGlobalTransactionScanner( "springbootオーダー"、 "my_test_tx_group")。}

実際には、Seata取引に関する最初の一連の作業はここで行われています。

4、構成レジストリ

Seataサーバーに接続している場合、一部の設定項目を必要とし、そこにある。この時registry.confあなたは何のレジストリや設定ファイルはい]を指定することができ、ファイルが。

例えば、オプションの多くがありますfile、nacos 、apollo、zk、consul

ファイルがそこにある理由4バックは、成熟した業界の構成レジストリの製品ですか?

公式の意図は、レジストリに基づいて迅速な統合テストを設定するには、第三者に依存しないseata機能が、file型自体は、動的発見と動的構成機能レジストリを持っていません。

registry.conf次のようにドキュメントを読み取ります。

レジストリ{タイプ= "ファイル" ファイル{NAME = "file.conf"}}設定{#ファイル、ナコス、アポロ、ZK、領事タイプ= "ファイル" ファイル{NAME = "file.conf"}}

あなたが選択した場合fileのタイプを、名前属性に指定file.conf、このファイルは、クライアントまたはサーバの構成情報に指定されています。例えば、トランスポートプロトコル、サーバのアドレス。

サービス{#vgroup-> rgroup    
vgroup_mapping.my_test_tx_group = "デフォルト"    
#only単一ノードサポート    
= "127.0.0.1:8091" default.grouplistを    
サポートしていない電流を#degrade    
enableDegrade =偽    
=偽#disable無効を  
}

第三に、ビジネスコード

1.インベントリサービス

在庫サービスでは、商品コードや購入の合計数を取得するには、控除をすることができます。

<更新ID = "decreaseStorage">更新t_storage設定したカウント=カウント -  $ {カウント}ここcommodity_code =#{commodityCode} </更新>

ダボはその後、公開するために、インベントリサービス・インターフェースが差し引かれます。

2、注文サービス

注文サービス、最初の控除インベントリでは、その後、順序を作成します。最後に、例外がスローされ、トランザクションがロールバックされているかどうかをチェックするためにデータベースにアクセスしてください。

公共のボイドcreateOrder @GlobalTransactional(OrderDTO orderDTO){ 
System.out.printlnは( "グローバル・トランザクションスタート= .XID" + RootContext.getXID());  
StorageDTO storageDTO新しい新StorageDTO =();  
storageDTO.setCount(orderDTO.getCount()) ;  
storageDTO.setCommodityCode(orderDTO.getCommodityCode());  
// 1、控除ストックstorageDubboService.decreaseStorage(storageDTO);  
// 2、注文orderDTO.setId(order_id.incrementAndGetを())を作成し、  
orderDTO.setOrderNo(UUID.randomUUID ().toString());  
オーダオーダ=新新秩序(); 
 BeanUtils.copyProperties(orderDTO、注文);  
 orderMapper.createOrder(注文);  
 スロー新新のRuntimeException( "分散トランザクション異常..." + orderDTO.getOrderNo( )); 
  }

取引注文サービスメソッドの初めに、マークする必要があり、ことは注目に値します@GlobalTransactionalまた、サービスのインベントリメソッドは、トランザクションがダボを介して広がることになる、このコメントは必要ありません。

IV注意事項

図1に示すように、データ・ソース

覚えておいてください、Seataのトランザクションブランチがプロキシデータソースによって達成され、データソースの代理を設定することを忘れてはなりません。

2、主キーの増分

データベースでは、テーブルには、成長している分野の主キーのIDです。あなたのフィールドがインクリメントされない場合は、MyBatisの中でinsert SQL、カラム名、あなたは完全に書きたいです。

たとえば、私たちはSQLを書くことができます。

(值1、值2、...)TABLE_NAME値にINSERT

したがって、この時間は、それは次のように記述する必要があります。

TABLE_NAME(カラム1、カラム2、...)VALUES。INSERT INTO(値1、値2、...)

3、シリアル化の問題

ためには、amountフィールドタイプdoubleseata0.6.1リリース、デフォルトの直列化の方法fastjson、それは、このフィールドにシリアライズされbigdecimal、タイプ型の不一致をバック引き起こす可能性があります。

しかし、その後にseata0.7.0バージョン(まだリリースされていない)、それはデフォルトのシリアライズに変更されましたjackson

しかし、心配する必要は、これは一般的な問題ではありません。著者は、問題を見つけるにつながるリードパック、ので間違いです。

図4に示すように、この記事のコード

このサンプルコードhttps://github.com/taoxun/springboot-dubbo-zookeeper-seataの記事:


おすすめ

転載: blog.51cto.com/14378044/2416230