《微服务实战》 第三十章 分布式事务框架seata TCC模式

简介: 《微服务实战》 第三十章 分布式事务框架seata TCC模式

前言

本章节介绍分布式事务框架seata TCC模式,上一章节介绍seata以及集成到Springboot、微服务框架里。

1、TCC模式

一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段 prepare 行为
  • 二阶段 commit 或 rollback 行为

根据两阶段行为模式的不同,我们将分支事务划分为 Automatic (Branch) Transaction Mode 和 TCC (Branch) Transaction Mode.

1.1、AT 模式(参考链接 TBD)基于 支持本地 ACID 事务 的 关系型数据库

1.1.1、 一阶段 prepare 行为

在本地事务中,一并提交业务数据更新和相应回滚日志记录。

1.1.2、二阶段 commit 行为

马上成功结束,自动 异步批量清理回滚日志。

1.1.3、二阶段 rollback 行为

通过回滚日志,自动 生成补偿操作,完成数据回滚。

1.2、TCC 模式,不依赖于底层数据资源的事务支持

1.2.1、一阶段 prepare 行为

调用 自定义 的 prepare 逻辑。try

1.2.2、二阶段 commit 行为

调用 自定义 的 commit 逻辑。confirm

1.2.3、二阶段 rollback 行为

调用 自定义 的 rollback 逻辑。cancel

2、例子

2.1、定义controller

/**
 * 采购
 */
@PostMapping("/purchaseTCC")
@GlobalTransactional
public String purchaseTCC(@RequestBody OrderDTO orderDTO){
    this.businessTCCService.purchase(orderDTO);
    return "success";
}

2.2、定义service

@LocalTCC
public interface BusinessTCCService {
    /**
     * 采购 执行资源检查及预留操作
     */
    @TwoPhaseBusinessAction(name = "purchase",commitMethod = "commit",rollbackMethod = "rollback")
    public void purchase(@BusinessActionContextParameter(paramName = "orderDTO") OrderDTO orderDTO);
    /**
     * 全局事务进行提交
     * @param businessActionContext
     * @return
     */
    boolean commit(BusinessActionContext businessActionContext);
    /**
     * 全局事务进行不回滚
     * @param businessActionContext
     * @return
     */
    boolean rollback(BusinessActionContext businessActionContext);
}
package com.xxxx.store.business.service.impl;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxxx.store.business.service.BusinessService;
import com.xxxx.store.business.service.BusinessTCCService;
import com.xxxx.store.business.service.OrderService;
import com.xxxx.store.business.service.StorageService;
import com.xxxx.store.common.dto.OrderDTO;
import com.xxxx.store.common.dto.StorageDTO;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
@Service
public class BusinessTCCServiceImpl implements BusinessTCCService {
    @Value("${file.path}")
    private String filePath;
    @Autowired
    private OrderService orderService;
    @Autowired
    private StorageService storageService;
    @Override
    public void purchase(OrderDTO orderDTO) {
        //减库存
        this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));
        //创建订单
        this.orderService.create(orderDTO);
    }
    @Override
    public boolean commit(BusinessActionContext businessActionContext) {
        System.out.println("事务ID:" + businessActionContext.getXid());
        return true;
    }
    @Override
    public boolean rollback(BusinessActionContext businessActionContext) {
        JSONObject jSONObject = (JSONObject)businessActionContext.getActionContext("orderDTO");
        OrderDTO orderDTO = jSONObject.toJavaObject(OrderDTO.class);
        StorageDTO storageDTO = new StorageDTO(null, orderDTO.getCommodityCode(), orderDTO.getCount());
        String s = JSON.toJSONString(storageDTO);
        String md5 = SecureUtil.md5(s);
        System.out.println("**************触发回滚操作:" + filePath + md5);
        File file = new File(filePath + md5);
        file.delete();
        return true;
    }
    /*@Override
    public void purchase(OrderDTO orderDTO) {
        //减库存
        this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));
        //创建订单
        this.orderService.create(orderDTO);
    }*/
}
注解 描述
@LocalTCC 一定需要注解在接口上,否则不生效,此接口可以是寻常的业务接口,只要实现了TCC的两阶段提交对应方法便可,适用于SpringCloud+Feign模式下的TCC。
@TwoPhaseBusinessAction 注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,自动调用提交方法或者回滚方法。
@BusinessActionContextParameter 使用该注解可以将参数传递到二阶段commit或者rollback的方法中,方便调用。
BusinessActionContext TCC事务上下文,使用BusinessActionContext.getActionContext(“params”)便可以得到一阶段try中定义的参数,在二阶段参考此参数进行业务回滚操作。

建议:可以在try方法中使用@Transational,直接通过spring来控制关系型数据库的事务,进行回滚的操作,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。

建议:try接口不可以捕获异常,否则TCC将识别该操作为成功,直接执行二阶段commit方法。

目录
相关文章
|
1月前
|
运维 监控 Go
Go语言微服务实战与最佳实践
【2月更文挑战第14天】本文将深入探讨使用Go语言进行微服务实战中的最佳实践,包括服务拆分、API设计、并发处理、错误处理、服务治理与监控等方面。通过实际案例和详细步骤,我们将分享如何在Go语言环境中构建高效、稳定、可扩展的微服务系统。
|
2月前
|
消息中间件 设计模式 数据库
深入探讨后端微服务架构中的分布式事务处理
【2月更文挑战第6天】在当今互联网应用开发领域,后端微服务架构已经成为一种常见的设计模式。本文将深入探讨在后端微服务架构中如何有效处理分布式事务,包括事务管理、一致性保障和异常处理策略,帮助开发者更好地应对复杂的业务场景。
192 4
|
1月前
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
|
1月前
|
监控 数据库
在Seata中一张表使用了联合主键,在事务回滚时报异常,改为单个主键,就没有这个异常,如何解决?
在Seata中一张表使用了联合主键,在事务回滚时报异常,改为单个主键,就没有这个异常,如何解决?
|
2月前
|
关系型数据库 MySQL 数据库
分布式事务Seata
分布式事务Seata
|
2天前
|
SQL 存储 运维
分布式事务Seata实践(上)
分布式事务Seata实践
8 0
|
19天前
|
存储 分布式数据库
GaussDB分布式与单机模式的比较
【4月更文挑战第7天】GaussDB分布式与单机模式的比较
1615 5
|
27天前
|
SQL 数据库 Windows
SpringCloud集成seata分布式事务控制
SpringCloud集成seata分布式事务控制
16 0
|
30天前
|
存储 监控 安全
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
68 1
|
30天前
|
Java fastjson 数据安全/隐私保护
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
40 0

热门文章

最新文章