Spring Cloud integrated seata distributed transaction-TCC mode

This article will introduce based springcloud + feign use Alibaba framework seata distributed transaction TCC mode (version 1.0.0), in the previous article has been introduced, AT mode can basically meet the demand we use distributed transactions 80%. However, the operation of non-relational databases and middleware (such as redis, etc.), the call of cross-company services, and the call of cross-language applications need to be combined with the TCC mode. For the introduction of seata, please click here to enter the official website of seata .

 1. The concept of TCC model

A distributed global transaction is a two-phase commit (Try-[Comfirm/Cancel]) model as a whole. In SEATA, both AT mode and TCC mode are actually implemented based on two-phase submission. Their difference lies in:

The AT mode is based on   a  relational database that supports local ACID transactions :

  • One-stage prepare behavior: In a local transaction, business data updates and corresponding rollback log records are submitted together.
  • Two-stage commit behavior: It ends successfully immediately, and the  rollback logs are automatically cleaned up in batches asynchronously.
  • Two-stage rollback behavior: automatically  generate compensation operations through the rollback log to complete data rollback.

Correspondingly, the TCC mode does not depend on the transaction support of the underlying data resources:

  • One-stage prepare behavior: call  custom  prepare logic.
  • Two-stage commit behavior: call  custom  commit logic.
  • Two-stage rollback behavior: call  custom  rollback logic.

The so-called TCC mode refers to the support for incorporating  custom  branch transactions into the management of global transactions.

To summarize briefly, SEATA's TCC mode is a manual AT mode , which allows you to customize the two-stage processing logic without relying on the undo_log of the AT mode.

2. Prerequisite preparation

3. The construction of TM and TCC-RM (click here for the source code)

This chapter focuses on the implementation of TCC based on SpringCloud+Feign. The construction of the project is directly based on the source code

3.1 Construction of seata server

3.2 TM construction

3.3 Construction of TCC-RM

3.3.1 Define TCC interface

Since we are using SpringCloud+Feign, the call of Feign is based on http, so here we can use LocalTCC. It is worth noting that @LocalTCC must be annotated on the interface. This interface can be an ordinary business interface, as long as it implements the corresponding two-phase submission method of TCC.

  • @LocalTCC is suitable for TCC in SpringCloud+Feign mode
  • @TwoPhaseBusinessAction annotates the try method, where name is the bean name of the current tcc method, just write the method name (remember to be globally unique), commitMethod points to the submit method, and rollbackMethod points to the transaction rollback method. After specifying the three methods, seata will automatically call commit or rollback through the dynamic proxy according to the success or failure of the transaction.
  • @BusinessActionContextParameter annotation can pass parameters to the second phase (commitMethod/rollbackMethod) method.
  • BusinessActionContext refers to the TCC transaction context
/**
 * 这里定义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.2 Business realization of TCC interface

In order to ensure the simplicity of the code, Controller and Service are combined to explain here, but the actual project is not.

  • Using @Transational in the try method can directly roll back operations in the relational database through spring transactions, while the rollback operations of middleware such as non-relational databases can be handed over to the rollbackMethod method.
  • Use context.getActionContext("params") to get the parameters defined in the first stage try, and perform business rollback operations on these parameters in the second stage.
  • Note that it is also not possible to capture exceptions here (similarly to handle exceptions in the aspect), otherwise TCC will recognize the operation as a success, and directly execute commitMethod in the second stage.
  • The second stage commitMethod can be confirmed empty.
@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 related yml configuration (stand-alone version)

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

 

This completes the configuration of the seata-tcc mode.

Guess you like

Origin blog.csdn.net/bbcckkl/article/details/104524095