全部产品
云市场

TCC 防悬挂与幂等接入

更新时间:2020-03-16 12:53:45

TCC 防悬挂的目的是为了防止空回滚,即二阶段回滚方法比一阶段 try 方法先执行。TCC 幂等控制的目的是保证同一个分布式事务内,TCC 参与者的一阶段 try 方法会且只会被执行一次。

您可以根据以下步骤将 TCC 防悬挂与幂等配置在 TCC 参与者服务发布端的应用中:

  1. 创建表
  2. 配置 DAO
  3. 修改定义接口
  4. 修改实现接口

创建表

执行以下 DDL 语句,在业务数据库中创建表 dtx_tcc_action

  1. CREATE TABLE `dtx_tcc_action` (
  2. `action_id` varchar(96) NOT NULL COMMENT '分支事务号',
  3. `action_name` varchar(64) DEFAULT NULL COMMENT '参与者名称',
  4. `tx_id` varchar(128) NOT NULL COMMENT '主事务号',
  5. `action_group` varchar(32) DEFAULT NULL COMMENT 'action group',
  6. `status` varchar(10) DEFAULT NULL COMMENT '状态',
  7. `param_data` varchar(4000) DEFAULT NULL COMMENT '一阶段方法参数数据',
  8. `gmt_create` datetime NOT NULL COMMENT '创建时间',
  9. `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  10. `sharding_key` varchar(128) DEFAULT NULL COMMENT '分库分表字段',
  11. PRIMARY KEY (`action_id`) ,
  12. UNIQUE KEY `idx_tx_id` (`tx_id`, `action_name`)
  13. ) ;

配置 DAO

  • 如果用户使用的是 ibastis,需要配置如下 bean:

    1. <bean class="com.alipay.sofa.dtx.tcc.dao.ibatis.IbatisTccAntiSuspendDAO" >
    2. <property name="dataSource" ref="yourDataSourceBean" />
    3. </bean>
  • 如果用户使用的是 Mybatis,配置如下 bean:

    1. <bean class="com.alipay.sofa.dtx.tcc.dao.mybatis.MybatisTccAntiSuspendDAO" >
    2. <property name="dataSource" ref="yourDataSourceBean" />
    3. </bean>

注意:其中的dataSource 属性需配置成业务数据库的 DataSource bean。

修改定义接口

将 @TwoPhaseBusinessAction 注解的 antiSuspend 属性配置成 true,打开防悬挂功能:

  1. public interface TccAction {
  2. @TwoPhaseBusinessAction(name = "yourTccActionName", commitMethod = "confirm", rollbackMethod = "cancel", antiSuspend = true)
  3. public boolean try(BusinessActionContext businessActionContext, @ShardingKey int a, int b);
  4. public boolean confirm(BusinessActionContext businessActionContext);
  5. public boolean cancel(BusinessActionContext businessActionContext);
  6. }

注意:如果业务数据库分库分表,则需要在一阶段方法的分库分表参数前添加 @ShardingKey 注解,单库单表无需添加。

修改实现接口

在 TCC 参与者一阶段 try 方法中,业务的数据库事务内,调用 TccTransactionController.doAntiSuspendControl() 方法添加防悬挂记录:

  1. public class TccActionImpl implements TccAction{
  2. @Override
  3. public boolean try(BusinessActionContext businessActionContext, int a, int b){
  4. transactionTemplate.execute(new TransactionCallback<Object>() {
  5. @Override
  6. public Object doInTransaction(TransactionStatus status) {
  7. //手动防悬挂
  8. TccTransactionController.doAntiSuspendControl();
  9. }
  10. });
  11. }
  12. @Override
  13. public boolean confirm(BusinessActionContext businessActionContext){
  14. }
  15. @Override
  16. public boolean cancel(BusinessActionContext businessActionContext){
  17. }
  18. }