この記事では、ベースのスプリングクラウド+偽の使用Alibabaフレームワークseata分散トランザクションTCCモード(バージョン1.0.0)を紹介します。前の記事で紹介したように、ATモードは基本的に分散トランザクションを使用する需要を80%満たすことができます。ただし、非リレーショナルデータベースとミドルウェア(redisなど)の操作、企業間サービスの呼び出し、および言語間アプリケーションの呼び出しは、TCCモードと組み合わせる必要があります。シータのご紹介はこちらからシータの公式サイトへお入りください。
1.TCCモデルの概念
分散グローバルトランザクションは、全体として2フェーズのコミット(試行-[確認/キャンセル])モデルです。SEATAでは、ATモードとTCCモードの両方が、実際には2フェーズの送信に基づいて実装されます。それらの違いは次のとおりです。
ATモードは、ローカルACIDトランザクションをサポート するリレーショナルデータベースに基づいて い ます。
- 1段階の準備動作:ローカルトランザクションでは、ビジネスデータの更新と対応するロールバックログレコードが一緒に送信されます。
- 2段階のコミット動作:すぐに正常に終了し 、ロールバックログを自動的かつ非同期にバッチ処理します。
- 2段階のロールバック動作:ロールバックログを介して 補正操作を自動的に生成し、データのロールバックを完了します。
同様に、TCCモードは、基盤となるデータリソースのトランザクションサポートに依存しません。
- 1段階の準備動作:カスタム 準備ロジックを呼び出し ます。
- 2段階のコミット動作:カスタム コミットロジックを呼び出し ます。
- 2段階のロールバック動作:カスタム ロールバックロジックを呼び出し ます。
いわゆるTCCモードは、カスタム ブランチトランザクションをグローバルトランザクションの管理に組み込むためのサポートを指します 。
簡単にまとめると、SEATAのTCCモードは手動ATモードであり、ATモードのundo_logに依存せずに2段階の処理ロジックをカスタマイズできます。
2.前提条件の準備
3. TMおよびTCC-RMの構築(ソースコードはここをクリック)
この章では、SpringCloud + Feignに基づくTCCの実装に焦点を当て、プロジェクトの構築はソースコードに直接基づいています。
3.1シータサーバーの構築
3.2TM構造
3.3TCC-RMの構築
3.3.1TCCインターフェースを定義する
SpringCloud + Feignを使用しているため、Feignの呼び出しはhttpに基づいているため、ここではLocalTCCを使用できます。@LocalTCCは、インターフェイスで注釈を付ける必要があることに注意してください。このインターフェイスは、TCCの対応する2フェーズ送信方法を実装している限り、通常のビジネスインターフェイスにすることができます。
- @LocalTCCは、SpringCloud + FeignモードのTCCに適しています
- @TwoPhaseBusinessActionはtryメソッドに注釈を付けます。nameは現在のtccメソッドのBean名であり、メソッド名を書き込むだけです(グローバルに一意であることを忘れないでください)。commitMethodはsubmitメソッドを指し、rollbackMethodはトランザクションロールバックメソッドを指します。3つのメソッドを指定した後、seataは、トランザクションの成功または失敗に応じて、動的プロキシを介してコミットまたはロールバックを自動的に呼び出します。
- @BusinessActionContextParameterアノテーションは、パラメーターを2番目のフェーズ(commitMethod / rollbackMethod)メソッドに渡すことができます。
- BusinessActionContextは、TCCトランザクションコンテキストを参照します
/**
* 这里定义tcc的接口
* 一定要定义在接口上
* 我们使用springCloud的远程调用
* 那么这里使用LocalTCC便可
*
* @author tanzj
*/
@LocalTCC
public interface TccService {
/**
* 定义两阶段提交
* name = 该tcc的bean名称,全局唯一
* commitMethod = commit 为二阶段确认方法
* rollbackMethod = rollback 为二阶段取消方法
* BusinessActionContextParameter注解 可传递参数到二阶段方法
*
* @param params -入参
* @return String
*/
@TwoPhaseBusinessAction(name = "insert", commitMethod = "commitTcc", rollbackMethod = "cancel")
String insert(
@BusinessActionContextParameter(paramName = "params") Map<String, String> params
);
/**
* 确认方法、可以另命名,但要保证与commitMethod一致
* context可以传递try方法的参数
*
* @param context 上下文
* @return boolean
*/
boolean commitTcc(BusinessActionContext context);
/**
* 二阶段取消方法
*
* @param context 上下文
* @return boolean
*/
boolean cancel(BusinessActionContext context);
}
3.3.2TCCインターフェースのビジネス実現
コードを単純化するために、コントローラーとサービスを組み合わせてここで説明しますが、実際のプロジェクトはそうではありません。
- tryメソッドで@Transationalを使用すると、Springトランザクションを介してリレーショナルデータベースの操作を直接ロールバックできますが、非リレーショナルデータベースなどのミドルウェアのロールバック操作はrollbackMethodメソッドに引き渡すことができます。
- context.getActionContext( "params")を使用して、第1段階の試行で定義されたパラメーターを取得し、第2段階でこれらのパラメーターに対してビジネスロールバック操作を実行します。
- ここで例外をキャプチャすることもできないことに注意してください(アスペクトで例外を処理する場合と同様)。そうしないと、TCCは操作を成功として認識し、第2段階でcommitMethodを直接実行します。
- 第2段階のcommitMethodは空であることを確認できます。
@Slf4j
@RestController
public class TccServiceImpl implements TccService {
@Autowired
TccDAO tccDAO;
/**
* tcc服务t(try)方法
* 实际业务方法
*
* @param params - name
* @return String
*/
@Override
@PostMapping("/tcc-insert")
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String insert(@RequestBody Map<String, String> params) {
log.info("------------------> xid = " + RootContext.getXID());
//实际的操作,或操作MQ、redis等
tccDAO.insert(params);
//throw new RuntimeException("服务tcc测试回滚");
return "success";
}
/**
* tcc服务 confirm方法
* 可以空确认
*
* @param context 上下文
* @return boolean
*/
@Override
public boolean commitTcc(BusinessActionContext context) {
log.info("xid = " + context.getXid() + "提交成功");
return true;
}
/**
* tcc 服务 cancel方法
*
* @param context 上下文
* @return boolean
*/
@Override
public boolean cancel(BusinessActionContext context) {
//todo 这里写中间件、非关系型数据库的回滚操作
System.out.println("please manually rollback this data:" + context.getActionContext("params"));
return true;
}
}
3.3.3 Seata関連のyml構成(スタンドアロンバージョン)
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: seataGroup-${seata.application-id}
service:
vgroup-mapping: default
grouplist: 127.0.0.1:8091
config:
type: file
file:
name: file.conf
registry:
type: nacos
file:
name: file.conf
これで、seata-tccモードの構成は完了です。