tcc-transaction分布式TCC型事務フレーム構築と使用記録



まずフレームワークの作者に感謝します.本文は枠组みだけを绍介します.ソースの分析はしません.
紹介:tccc-tractionはオープンソースのTCC補完的分散式事務フレームで、gitアドレス:https://github.com/changmingxie/tcc-transaction 
TCCはTry、Confirm、Cancelの略語である.try段階で予約した資源を提出してみて、confirm段階で提出することを確定し、cancelはキャンセルして釈放資源を提出する.
1.2.xプロジェクトガイドの住所:https://github.com/changmingxie/tcc-transaction/wiki/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%971.2.x 
 
本論文の例は、資産を作成し、同時にMongoとESの流れに資産情報を同期させる(ESコードはリストされていません.monogoと似ています.)流れ全体の保証データが一致しています.
 
コードとプロセス:
1.1.2.xバージョンのソースコードをダウンロードし、一部のコードを修正する必要があります.
第三者カバンなので、自分で地元の倉庫に持ち帰ります.しかし、パッケージの中のspringバージョンは3.2.RELEASEで、ローカルプロジェクトが4.xの場合、例えば本人のプロジェクトspringバージョンは4.3.40.RELEASEで、tccのspringバージョンを修正しないと、エラーが発生しません.
ソースの修正は簡単です.以下の通りです.
1.1 tcc-tractionの総pom.xmlファイルを修正する 
 

4.3.4.RELEASE



      org.quartz-scheduler
      quartz
      2.2.1
      
          
              c3p0
              c3p0
          
      




       com.alibaba
       dubbo
       2.5.3
 
 
 
1.2変更 tccc-tractionn-spring/src/main/java/org/mengyun/tcctransaction/spring/recover/RecoverScheduledJob.java 
このファイルには CronTriggerBeanは4.xの中にはもう存在しなくなりました.ソースを修正する主な修正点です.
その中のinit方法を修正して、修正後は以下の通りです.
 
public void init() {

        try {
            MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
            jobDetail.setTargetObject(transactionRecovery);
            jobDetail.setTargetMethod("startRecover");
            jobDetail.setName("transactionRecoveryJob");
            jobDetail.setConcurrent(false);
            jobDetail.afterPropertiesSet();

            CronTriggerFactoryBean cronTrigger = new CronTriggerFactoryBean();
            cronTrigger.setBeanName("transactionRecoveryCronTrigger");
            cronTrigger.setJobDetail(jobDetail.getObject());

            cronTrigger.setCronExpression(transactionConfigurator.getRecoverConfig().getCronExpression());
            cronTrigger.afterPropertiesSet();

            scheduler.scheduleJob(jobDetail.getObject(), cronTrigger.getObject());

            scheduler.start();

        } catch (Exception e) {
            throw new SystemException(e);
        }
    }
以下の修正も参照できます.https://github.com/changmingxie/tcc-transaction/pull/84/files 
 
 
1.3包装して発表する
mvn-Dmaven.test.skyp=true install
 
2.プロジェクト依存
1.2.xマニュアルを参照して、二つの依存性を導入します.(本人プロジェクトはSOAアーキテクチャdubbフレームを使用しています.私は1.2.3.1のバージョンを使用して包装します.)呼び出し側と提供側の両方に依存を導入する必要があります.
 
3.tcc-tractions.xmlの読み込み設定
本文はweb.xmlに配置されていますが、個人的にdubb webプロジェクトのweb.xmlに入れてみましたが、設定はロードされていません.このファイルの意味はプロジェクト起動時にロードされたいだけで、Dubbの中のspringの配置ファイルに直接導入されます.
 

このファイルには各種のaopロジックがあります.プロジェクト起動時に指定された注釈をスキャンして強調します.
 
 
4.Transation Repositoryを設定する
tccのためにデータソースを設定する必要があります.msqlまたは他のnosqlでもいいです.本明細書ではmsyqlを使用します.他は元のマニュアルドキュメントを参照してください.
mysqlの配置は以下の通りです.
 


	
	
	
	
	
	
	
	
	
	
	
	



	
	
	



	
	
	
	
		
			com.alibaba.dubbo.remoting.TimeoutException
		
	
データソースは新しいものを配置しなければなりません.以前のプロジェクトに存在したdataSourceのbeanを使用することができません.同じライブラリの中にも入れられません.そうしないと、tccテーブルのデータは地元の事務と一緒にロールバックし、異常な事務ログを保存できなくなります.2.domann、tbSuffixの配置に注意してください.この二つの文書には配置されていませんが、ソースコードのdemoには配置されています.データベースに使う表の名前など、配置を推奨します.3.最後のDefaultRecoverConfig項目はオプションで、回復と再試行のために、具体的な役割はマニュアルを参照してください.4.default AutoCommtはtrueでなければなりません(デフォルトはtrueです)
 
 
5.mysql建表脚本
以上のtbSufix構成によると、脚本は以下の通りです.
 
CREATE TABLE `tcc_transaction_asset` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
表の名前が間違っていると、起動過程がエラーとなりますので、それに応じて調整すればいいです.
 
 
6.サービスのリリース(重点)
6.1 dubboインターフェース
 
public interface AssetCardService {

    /**
     *        (      )
     */
    @Compensable
    int testSaveAssetCard(AssetCardModel model);

    /**
     *        mysql(     )
     */
    int confirmMysqlSaveAssetCard(AssetCardModel model);

    /**
     *        msyql(       )
     */
    int cancelMysqlSaveAssetCard(AssetCardModel model);

    /**
     *       mongo(      )
     */
    @Compensable
    void processMongo(AssetCardModel model);

    /**
     *        mongo(     )
     */
    void confirmMongoSaveAssetCard(AssetCardModel model);

    /**
     *        mongo(       )
     */
    void cancelMongoSaveAssetCard(AssetCardModel model);

}
注意すべき点:1.対外サービスを提供するインターフェースには@Compnsableの注釈が必要です.2.対応するconfirmとcancel方法はインターフェースとして宣言しなければならず、prvateとして声明できない.publicでもだめで、インターフェースが必要である.
 
 
6.2 dubboインターフェース実現クラス
 
    @Override
    @Compensable(confirmMethod = "confirmMysqlSaveAssetCard", cancelMethod = "cancelMysqlSaveAssetCard", transactionContextEditor = DubboTransactionContextEditor.class)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
    public int testSaveAssetCard(AssetCardModel model){

        //   mysql,data   -1
        model.setDataStatus(-1);
        assetCardDao.insert(model);


        // mongo  
        assetCardService.processMongo(model);

        return model.getId();
    }

    @Override
    public int confirmMysqlSaveAssetCard(AssetCardModel model){
        System.out.println("============================================================================");
        System.out.println("=================mysql:confirm");
        System.out.println("============================================================================");

        //   mysql data_status 0
        model.setDataStatus(0);
        assetCardDao.updateByPrimaryKey(model);

        return model.getId();
    }

    @Override
    public int cancelMysqlSaveAssetCard(AssetCardModel model){
        System.out.println("============================================================================");
        System.out.println("=================mysql:cancel");
        System.out.println("============================================================================");

        //   mysql data_status -1
        model.setDataStatus(-1);
        assetCardDao.updateByPrimaryKey(model);

        return model.getId();
    }

    @Compensable(confirmMethod = "confirmMongoSaveAssetCard", cancelMethod = "cancelMongoSaveAssetCard", transactionContextEditor = DubboTransactionContextEditor.class)
    @Override
    public void processMongo(AssetCardModel model) {

        //   mongo,data_statu -1
        model.setDataStatus(-1);
        assetCardDaoWrapper.saveMongo(model);
    }

    @Override
    public void confirmMongoSaveAssetCard(AssetCardModel model){
        System.out.println("============================================================================");
        System.out.println("=================mongo:confirm");
        System.out.println("============================================================================");

        //   mongo data_status 0
        model.setDataStatus(0);
        assetCardDaoWrapper.updateMongo(model);
    }

    @Override
    public void cancelMongoSaveAssetCard(AssetCardModel model){
        System.out.println("============================================================================");
        System.out.println("=================mongo:cancel");
        System.out.println("============================================================================");

        //   mongo data_status -1
        model.setDataStatus(-1);
        assetCardDao.updateByPrimaryKey(model);
        assetCardDaoWrapper.updateMongo(model);
    }
 
 
説明と注意点:1.対外的にサービスを提供するインターフェースには@Compnsableの注釈が必要であり、同時にconfirmMethod、cancel Methodパラメータの配置が必要であると同時に、dubboインターフェースには「trantionContect Editor=DubboTranct Conters.class」という構成が追加されています.2.サービスインターフェースを提供することは、他の2つのCC方法のパラメータに対応することと完全に一致していなければならない.3.このtccフレームはネストコールできます.testSaveAsssetCard方法、つまりtry段階で別のtcc方法を呼び出しました.「asetCard Service.processMongo()」で、理論的に入れ子はtry段階で行うべきです.4.confirm、cancelはべき乗などの性を実現する必要があり、再試行される可能性があります.5.ネットなどにより、キャンセル方法が先に実行される可能性がありますので、キャンセル方法は必ず判断と処理をしてください.
 
6.3呼び出し元
 
 
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
public long testSaveAssetCard(AssetCardModel assetCardModel) throws AssetException {
    
    assetCardModel.setId(IdGenerator.getId());  
    return assetCardService.testSaveAssetCard(assetCardModel);
}
注意点:1.リフォームなどの操作が必要ですので、この業務ではidは自己増加ではなく、プロジェクト生成が必要です.2.特に注意したいのですが、呼び出し側は事務中でなければならないということは、事務の注釈が必要であり、或いは事務の配置によって切ってもいいです.事務tccフレームがない場合は異常を投げます.
 
これで設定は全部完了しました.
 
7.事務ビュー
ソースはtcc-tractionn-server webプロジェクトを提供しています.このプロジェクトはインタフェースを提供して事務日誌を調べて、中の配置ファイルを修正して、包装してから配置すればいいです.
 
用意:
業務フロー使用記録:
前提:ユーザーが注文し、注文書を作成し、支払い記録を作成し、支払い記録状態は未払いです.
try:
    ユーザー金額の凍結
    ポイント処理TCCを呼び出します.
    try:ポイントの追加を予定しています.
    confirm:更新してポイントの状態を増加します.
    cancel:増加したポイントをキャンセルします.
 confirm:
    注文書の支払い状態をすでに支払済みに更新しました.
    注文書の支払い記録の支払い状態をすでに支払済みに更新しました. 
    ユーザー金額の差し引き(以上の三つの操作は同じローカル事務)
キャンセル:
    注文書の支払い状態と注文記録の支払い状態が未払いと判断します.    ユーザ凍結金額釈放 
 
2019年初頭からの後続:このフレームの侵入性は比較的に大きく、コードを重くし、長所は表に表さない.Fescarの成熟が楽しみです.