Skip to content

2 快速开始

changmingxie edited this page Mar 2, 2022 · 35 revisions

让我们从一个微服务示例开始。

用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

支付服务:根据采购需求创建订单,发起支付。

资金服务:从用户资金帐户中扣除余额。

红包服务:从用户红包账户中扣除余额。

微服务部署架构图

架构图

红包服务:

public interface RedPacketTradeOrderService {

    public String record(RedPacketTradeOrderDto tradeOrderDto);
}

资金服务:

public interface CapitalTradeOrderService {

    public String record(CapitalTradeOrderDto tradeOrderDto);

}

支付服务:

public void makePayment(String orderNo) {
    System.out.println("order try make payment called.time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

    Order order = orderRepository.findByMerchantOrderNo(orderNo);

    String result = capitalTradeOrderService.record(buildCapitalTradeOrderDto(order));
    String result2 = redPacketTradeOrderService.record(buildRedPacketTradeOrderDto(order));
}

提供支持的示例

示例包含tcc-transaction-dubbo-sample 和 tcc-transaction-http-sample 两个。这两个示例业务模型内容是一样的,区别在于rpc不一样,tcc-transaction-dubbo-sample 演示使用隐式传参的方式传输tcc-transaction在rpc调用过程中需要传输的参数TransactionContext,而tcc-transaction-http-sample演示使用显示传参(接口方法中定义TransactionContext参数)。

tcc-transaction-dubbo-sample配置

  1. 配置tcc-transaction-dubbo-capital

1.1 生效tcc-transaction

在spring项目中可以使用xml配置或者注解来生效tcc-transaction。

a. XML配置

    <tcc:annotation-driven transaction-repository="transactionRepository"/>

b. 注解配置

    @EnableTccTransaction

1.2 配置transaction repository

transaction repository用来保存事务日志,框架提供多种Transaction Repository:

TransactionRepository 类图

 在tcc-transaction-dubbo-sample中使用MemoryStoreTransactionRepository(没有持久化能力,仅可用于测试):

    <bean id="transactionRepository" class="org.mengyun.tcctransaction.repository.MemoryStoreTransactionRepository">
        <property name="domain" value="TCC:DUBBO:CAPITAL:"/>
    </bean>

1.3 声明tcc接口

在接口方法上加上@EnableTcc(1.7.x新增注解,1.6.x是@Compensable)将提供的接口标记为tcc接口:

     public interface CapitalTradeOrderService {
        @EnableTcc
        public String record(CapitalTradeOrderDto tradeOrderDto);

    }

1.4 配置TCC事务的Try、Confirm、Cancel方法:

在tcc接口实现上方法上添加@Compensable注解,设置confirmMethod和cancelMethod方法,分别为tcc的confirm和cancel方法。

    @Override
    @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class)
    @Transactional
    public String record(CapitalTradeOrderDto tradeOrderDto) {
        ...
    }
  1. 配置tcc-transaction-dubbo-redpacket

配置生效tcc-transaction 和 transactionRepository和配置tcc-transaction-dubbo-captial类似,在此不做赘述。

2.1 声明tcc接口

在接口方法上加上@EnableTcc将提供的接口标记为tcc接口:

     public interface RedPacketTradeOrderService {

        @EnableTcc
        public String record(RedPacketTradeOrderDto tradeOrderDto);
    }

2.2 配置TCC事务的Try、Confirm、Cancel方法:

在tcc接口实现上方法上添加@Compensable注解,设置confirmMethod和cancelMethod方法,分别为tcc的confirm和cancel方法。

@Override
@Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = DubboTransactionContextEditor.class)
@Transactional
public String record(RedPacketTradeOrderDto tradeOrderDto) {
    ...
}
  1. 配置tcc-transaction-dubbo-order

配置生效tcc-transaction 和 transactionRepository和配置tcc-transaction-dubbo-captial类似,在此不做赘述。

3.1 配置TCC事务的Try、Confirm、Cancel方法:

在tcc实现上方法上添加@Compensable注解,设置confirmMethod和cancelMethod方法,分别为tcc的confirm和cancel方法。

   @Compensable(confirmMethod = "confirmMakePayment", cancelMethod = "cancelMakePayment", asyncConfirm = false)
   public void makePayment(@UniqueIdentity String orderNo) {
        System.out.println("order try make payment called.time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

        Order order = orderRepository.findByMerchantOrderNo(orderNo);

        String result = capitalTradeOrderService.record(buildCapitalTradeOrderDto(order));
        String result2 = redPacketTradeOrderService.record(buildRedPacketTradeOrderDto(order));
   }

TCC事务的confirm和cancel方法的声明必须和try方法一致。confirmMakePayment、cancelMakePayment方法声明如下:

    void confirmMakePayment(String orderNo);
    void cancelMakePayment(String orderNo);

3.2 添加tcc-transaction-dubbo jar依赖

在pom.xml中添加jar依赖

        <dependency>
            <groupId>org.mengyun</groupId>
            <artifactId>tcc-transaction-dubbo</artifactId>
            <version>${project.version}</version>
        </dependency>

至此,三个服务的TCC配置完成,分别启动这三个服务。

tcc-transaction-http-sample配置

  1. 配置tcc-transaction-http-capital

配置生效tcc-transaction 和 transactionRepository和配置tcc-transaction-dubbo-captial类似,在此不做赘述。

1.1 声明tcc接口

在CapitalTradeOrderService接口方法入参上加上TransactionContext 将提供的接口标记为tcc接口,该示例演示显示传参:

     public interface CapitalTradeOrderService {
        public String record(TransactionContext transactionContext, CapitalTradeOrderDto tradeOrderDto);
    }

1.2 配置TCC事务的Try、Confirm、Cancel方法:

在CapitalTradeOrderServiceImpl实现类的tcc方法上添加@Compensable注解,并提供confirm方法和cancel方法

    @Override
    @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord")
    @Transactional
    public String record(TransactionContext transactionContext, CapitalTradeOrderDto tradeOrderDto) {
        ...
    }
  1. 配置tcc-transaction-http-redpacket

配置生效tcc-transaction 和 transactionRepository和配置tcc-transaction-dubbo-captial类似,在此不做赘述。

2.1 声明tcc接口

在RedPacketTradeOrderService接口方法入参上加上TransactionContext 将提供的接口标记为tcc接口,该示例演示显示传参:

     public interface RedPacketTradeOrderService {

        public String record(TransactionContext transactionContext, RedPacketTradeOrderDto tradeOrderDto);
     }

2.2 配置TCC事务的Try、Confirm、Cancel方法:

在RedPacketTradeOrderServiceImpl实现类的tcc方法上添加@Compensable注解,并提供confirm方法和cancel方法

    @Override
    @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord")
    @Transactional
    public String record(TransactionContext transactionContext, CapitalTradeOrderDto tradeOrderDto) {
        ...
    }
  1. 配置tcc-transaction-http-order

配置生效tcc-transaction 和 transactionRepository和配置tcc-transaction-dubbo-captial类似,在此不做赘述。

3.1 配置TCC事务的Try、Confirm、Cancel方法:

在tcc实现上方法上添加@Compensable注解,设置confirmMethod和cancelMethod方法,分别为tcc的confirm和cancel方法。

       @Compensable(confirmMethod = "confirmMakePayment", cancelMethod = "cancelMakePayment", asyncConfirm = true)
       @Transactional
       public void makePayment(String orderNo) {

           System.out.println("order try make payment called.time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

           Order order = orderRepository.findByMerchantOrderNo(orderNo);

           String result = tradeOrderServiceProxy.record(buildCapitalTradeOrderDto(order));
           String result2 = tradeOrderServiceProxy.record(buildRedPacketTradeOrderDto(order));
       }

至此,三个服务的TCC配置完成,分别启动这三个服务。

部署事务后台管理平台

启动后台管理的服务端应用tcc-transaction-dashboard,设置端口如8888,再启动tcc-transaction-admin-web前端项目,选择一个domain,则可以查看日志信息。可以对每个日志进行人工操作。

运行sample project

以tcc-transaction-http-sample为例, tcc-transaction-dubbo-sample类似。

打开tcc-transaction-http-order的首页,点击"商品列表链接“,选择一个商品点击“购买”,出现如下图, 在红包抵扣项中输入红包扣款额度,如100,点击支付,系统进行资金账户扣款和红包账户扣款:

sample 支付

出现 支付成功页面,表示本次操作成功!

查看系统日志,验证系统日志打印顺序是否如下(可查看日志上的时间随项目执行时间而变):

a. try阶段:

1. order try make payment called.time seq:2021-06-01 17:44:32
2. capital try record called. time seq:2021-06-01 17:44:33
3. red packet try record called. time seq:2021-06-01 17:44:35

b. confirm阶段:

1. order confirm make payment called. time seq:2021-06-01 17:44:36
2. capital confirm record called. time seq:2021-06-01 17:44:37
3. red packet confirm record called. time seq:2021-06-01 17:44:38

恭喜你,顺序正确说明sample项目运行成功。