tcc-transaction 快速开始

发布于 2023-10-11 07:32:10 字数 8747 浏览 34 评论 0

让我们从一个微服务示例开始。用户购买商品的业务逻辑。整个业务逻辑由 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:

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

<bean 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,点击支付,系统进行资金账户扣款和红包账户扣款:

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

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

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 项目运行成功。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

悲歌长辞

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文