前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >tcc分布式事务框架解析

tcc分布式事务框架解析

作者头像
爱撸猫的杰
发布于 2019-03-28 07:00:28
发布于 2019-03-28 07:00:28
1.4K00
代码可运行
举报
文章被收录于专栏:爱撸猫的杰爱撸猫的杰
运行总次数:0
代码可运行

前言碎语

楼主之前推荐过2pc的分布式事务框架LCN。今天来详细聊聊TCC事务协议。

2pc实现:https://github.com/codingapi/tx-lcn

tcc实现:https://github.com/yu199195/hmily

首先我们了解下什么是tcc,如下图

tcc分布式事务协议控制整体业务事务分为三个阶段。

try:执行业务逻辑

confirm:确定业务逻辑执行无误后,确定业务逻辑执行完成

cancel:假如try阶段有问题,执行cancel阶段逻辑,取消try阶段的数据

这就需要我们在设计业务时,在try阶段多想想业务处理的折中状态,比如,处理中,支付中,进行中等,在confirm阶段变更为处理完成,或者在cancel阶段变更为处理失败。

下面以电商下单为例子:.

假设我们有一个电商下单的业务,有三个服务组成,订单服务处理下单逻辑,库存服务处理减库存逻辑,支付服务处理减账户余额逻辑。在下单服务里先后调用减库存和减余额的方法。如果使用tcc分布式事务来协调事务,我们服务就要做如下设计:

订单服务:

  • try:支付状态设置为支付中
  • confirm:设置为支付完成
  • cancel:设置为支付失败

库存服务:

多加一个锁定库存的字段记录,用于记录业务处理中状态

  • try:总库存-1,锁定库存+1
  • confirm:锁定库存-1
  • cancel:总库存+1,锁定库存-1

支付服务:

多加一个冻结金额的字段记录,用于记录业务处理中状态

  • try:余额-1,冻结金额+1
  • confirm:冻结金额-1
  • cancel:余额+1,冻结金额-1

tcc分布式事务在这里起到了一个事务协调者的角色。真实业务只需要调用try阶段的方法。confirm和cancel阶段的额方法由tcc框架来帮我们调用完成最终业务逻辑。下面我们假设如下三个场景的业务情况,看tcc如何协调业务最终一致的。

  1. 服务一切正常:所有服务的try方法执行后都没有问题,库存足够,余额足够。tcc事务协调器会触发订单服务的confirm方法,将订单更新为支付完成,触发库存服务的confirm方法锁定库存-1,触发支付服务的confirm方法冻结金额-1
  2. 库存服务故障,无法调通:这个时候订单已经生成,状态为待支付。当调用库存超时抛异常后,tcc事务协调器会触发订单服务的cancel方法将订单状态更新为支付失败。
  3. 支付服务故障,无法调通:这个时候订单已经生成,状态为待支付,总库存-1,锁定库存+1了。当调用支付服务超时抛异常时,tcc事务协调器会触发订单服务的cancel方法将订单状态更新为支付失败,触发库存服务的cancel方法将库存+1,锁定库存-1。

hmily事务框架怎么做的?

通过上面对tcc事务协议说明大家应该都了解了tcc的处理协调机制,下面我们来看看hmily是怎么做到的,我们以接入支持dubbo服务为例。

概要:首先最基础两个应用点是aop和dubbo的filter机制,其次针对一组事务,定义了启动事务处理器,参与事务处理器去协调处理不同的事务单元。外加一个disruptor+ScheduledService处理事务日志,补偿处理失败的事务。

hmily框架以@Hmily注解为切入点,定义了一个环绕织入的切面,注解必填两个参数confirmMethod和cancelMethod,也就是tcc协调的两个阶段方法。在需要tcc事务的方法上面加上这个注解,也就托管了tcc三个阶段的处理流程。下面是aspect切面的抽象类,不同的RPC框架支持会有不同的实现 。其中真正处理业务逻辑需要实现HmilyTransactionInterceptor接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Aspect
public abstract class AbstractHmilyTransactionAspect {

    private HmilyTransactionInterceptor hmilyTransactionInterceptor;

    protected void setHmilyTransactionInterceptor(final HmilyTransactionInterceptor hmilyTransactionInterceptor) {
        this.hmilyTransactionInterceptor = hmilyTransactionInterceptor;
    }

    /**
     * this is point cut with {@linkplain Hmily }.
     */
    @Pointcut("@annotation(org.dromara.hmily.annotation.Hmily)")
    public void hmilyInterceptor() {
    }

    /**
     * this is around in {@linkplain Hmily }.
     * @param proceedingJoinPoint proceedingJoinPoint
     * @return Object
     * @throws Throwable  Throwable
     */
    @Around("hmilyInterceptor()")
    public Object interceptTccMethod(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        return hmilyTransactionInterceptor.interceptor(proceedingJoinPoint);
    }

    /**
     * spring Order.
     *
     * @return int
     */
    public abstract int getOrder();
}

dubbo的aspect抽象实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Aspect
@Component
public class DubboHmilyTransactionAspect extends AbstractHmilyTransactionAspect implements Ordered {

    @Autowired
    public DubboHmilyTransactionAspect(final DubboHmilyTransactionInterceptor dubboHmilyTransactionInterceptor) {
        super.setHmilyTransactionInterceptor(dubboHmilyTransactionInterceptor);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

dubbo的HmilyTransactionInterceptor实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class DubboHmilyTransactionInterceptor implements HmilyTransactionInterceptor {

    private final HmilyTransactionAspectService hmilyTransactionAspectService;

    @Autowired
    public DubboHmilyTransactionInterceptor(final HmilyTransactionAspectService hmilyTransactionAspectService) {
        this.hmilyTransactionAspectService = hmilyTransactionAspectService;
    }

  @Override
public Object interceptor(final ProceedingJoinPoint pjp) throws Throwable {
    final String context = RpcContext.getContext().getAttachment(CommonConstant.HMILY_TRANSACTION_CONTEXT);
    HmilyTransactionContext hmilyTransactionContext;
    //判断dubbo上下文中是否携带了tcc事务,如果有就取出反序列化为事务上下文对象
    if (StringUtils.isNoneBlank(context)) {
        hmilyTransactionContext = GsonUtils.getInstance().fromJson(context, HmilyTransactionContext.class);
        RpcContext.getContext().getAttachments().remove(CommonConstant.HMILY_TRANSACTION_CONTEXT);
    } else {
        //如果dubbo上下文中没有,就从当前上下文中获取。如果是事务发起者,这里其实也获取不到事务
        hmilyTransactionContext = HmilyTransactionContextLocal.getInstance().get();
    }
    return hmilyTransactionAspectService.invoke(hmilyTransactionContext, pjp);
}

}

这里主要判断了dubbo上下文中是否携带了tcc事务。如果没有就从当前线程上下文中获取,如果是事务的发起者,这里其实获取不到事务上下文对象的。在invoke里有个获取事务处理器的逻辑,如果事务上下文入参 为null,那么获取到的就是启动事务处理器。启动事务处理器处理逻辑如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context)
        throws Throwable {
    System.err.println("StarterHmilyTransactionHandler");
    Object returnValue;
    try {
        HmilyTransaction hmilyTransaction = hmilyTransactionExecutor.begin(point);
        try {
            //execute try
            returnValue = point.proceed();
            hmilyTransaction.setStatus(HmilyActionEnum.TRYING.getCode());
            hmilyTransactionExecutor.updateStatus(hmilyTransaction);
        } catch (Throwable throwable) {
            //if exception ,execute cancel
            final HmilyTransaction currentTransaction = hmilyTransactionExecutor.getCurrentTransaction();
            executor.execute(() -> hmilyTransactionExecutor
                    .cancel(currentTransaction));
            throw throwable;
        }
        //execute confirm
        final HmilyTransaction currentTransaction = hmilyTransactionExecutor.getCurrentTransaction();
        executor.execute(() -> hmilyTransactionExecutor.confirm(currentTransaction));
    } finally {
        HmilyTransactionContextLocal.getInstance().remove();
        hmilyTransactionExecutor.remove();
    }
    return returnValue;
}

真正业务处理方法,point.proceed();被try,catch包起来了,如果try里面的方法出现异常,就会走hmilyTransactionExecutor.cancel(currentTransaction)的逻辑,如果成功,就走hmilyTransactionExecutor.confirm(currentTransaction)逻辑。其中cancel和confirm里都有协调参与者事务的处理逻辑,以confirm逻辑为例。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void confirm(final HmilyTransaction currentTransaction) throws HmilyRuntimeException {
    LogUtil.debug(LOGGER, () -> "tcc confirm .......!start");
    if (Objects.isNull(currentTransaction) || CollectionUtils.isEmpty(currentTransaction.getHmilyParticipants())) {
        return;
    }
    currentTransaction.setStatus(HmilyActionEnum.CONFIRMING.getCode());
    updateStatus(currentTransaction);
    final ListhmilyParticipants = currentTransaction.getHmilyParticipants();
    ListfailList = Lists.newArrayListWithCapacity(hmilyParticipants.size());
    boolean success = true;
    if (CollectionUtils.isNotEmpty(hmilyParticipants)) {
        for (HmilyParticipant hmilyParticipant : hmilyParticipants) {
            try {
                HmilyTransactionContext context = new HmilyTransactionContext();
                context.setAction(HmilyActionEnum.CONFIRMING.getCode());
                context.setRole(HmilyRoleEnum.START.getCode());
                context.setTransId(hmilyParticipant.getTransId());
                HmilyTransactionContextLocal.getInstance().set(context);
                executeParticipantMethod(hmilyParticipant.getConfirmHmilyInvocation());
            } catch (Exception e) {
                LogUtil.error(LOGGER, "execute confirm :{}", () -> e);
                success = false;
                failList.add(hmilyParticipant);
            } finally {
                HmilyTransactionContextLocal.getInstance().remove();
            }
        }
        executeHandler(success, currentTransaction, failList);
    }
}

可以看到executeParticipantMethod(hmilyParticipant.getConfirmHmilyInvocation()),这里执行了事务参与者的confirm方法。同理cancel里面也有类似代码,执行事务参与者的cancel方法。那么事务参与者的信息是怎么获取到的呢?我们需要回到一开始提到的dubbo的filter机制。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Activate(group = {Constants.SERVER_KEY, Constants.CONSUMER})
public class DubboHmilyTransactionFilter implements Filter {

    private HmilyTransactionExecutor hmilyTransactionExecutor;

    /**
     * this is init by dubbo spi
     * set hmilyTransactionExecutor.
     *
     * @param hmilyTransactionExecutor {@linkplain HmilyTransactionExecutor }
     */
    public void setHmilyTransactionExecutor(final HmilyTransactionExecutor hmilyTransactionExecutor) {
        this.hmilyTransactionExecutor = hmilyTransactionExecutor;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Result invoke(final Invoker invoker, final Invocation invocation) throws RpcException {
        String methodName = invocation.getMethodName();
        Class clazz = invoker.getInterface();
        Class[] args = invocation.getParameterTypes();
        final Object[] arguments = invocation.getArguments();
        converterParamsClass(args, arguments);
        Method method = null;
        Hmily hmily = null;
        try {
            method = clazz.getMethod(methodName, args);
            hmily = method.getAnnotation(Hmily.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        if (Objects.nonNull(hmily)) {
            try {
                final HmilyTransactionContext hmilyTransactionContext = HmilyTransactionContextLocal.getInstance().get();
                if (Objects.nonNull(hmilyTransactionContext)) {
                    if (hmilyTransactionContext.getRole() == HmilyRoleEnum.LOCAL.getCode()) {
                        hmilyTransactionContext.setRole(HmilyRoleEnum.INLINE.getCode());
                    }
                    RpcContext.getContext().setAttachment(CommonConstant.HMILY_TRANSACTION_CONTEXT, GsonUtils.getInstance().toJson(hmilyTransactionContext));
                }
                final Result result = invoker.invoke(invocation);
                //if result has not exception
                if (!result.hasException()) {
                    final HmilyParticipant hmilyParticipant = buildParticipant(hmilyTransactionContext, hmily, method, clazz, arguments, args);
                    if (hmilyTransactionContext.getRole() == HmilyRoleEnum.INLINE.getCode()) {
                        hmilyTransactionExecutor.registerByNested(hmilyTransactionContext.getTransId(),
                                hmilyParticipant);
                    } else {
                        hmilyTransactionExecutor.enlistParticipant(hmilyParticipant);
                    }
                } else {
                    throw new HmilyRuntimeException("rpc invoke exception{}", result.getException());
                }
                return result;
            } catch (RpcException e) {
                e.printStackTrace();
                throw e;
            }
        } else {
            return invoker.invoke(invocation);
        }
    }

    @SuppressWarnings("unchecked")
    private HmilyParticipant buildParticipant(final HmilyTransactionContext hmilyTransactionContext,
                                              final Hmily hmily,
                                              final Method method, final Class clazz,
                                              final Object[] arguments, final Class... args) throws HmilyRuntimeException {

        if (Objects.isNull(hmilyTransactionContext)
                || (HmilyActionEnum.TRYING.getCode() != hmilyTransactionContext.getAction())) {returnnull;}//获取协调方法String confirmMethodName = hmily.confirmMethod();if(StringUtils.isBlank(confirmMethodName)){
            confirmMethodName = method.getName();}String cancelMethodName = hmily.cancelMethod();if(StringUtils.isBlank(cancelMethodName)){
            cancelMethodName = method.getName();}HmilyInvocation confirmInvocation =newHmilyInvocation(clazz, confirmMethodName, args, arguments);HmilyInvocation cancelInvocation =newHmilyInvocation(clazz, cancelMethodName, args, arguments);//封装调用点returnnewHmilyParticipant(hmilyTransactionContext.getTransId(), confirmInvocation, cancelInvocation);}privatevoid converterParamsClass(finalClass[] args,finalObject[] arguments){if(arguments ==null|| arguments.length <1){return;}for(int i =0; i < arguments.length; i++){
            args[i]= arguments[i].getClass();}}}

需要注意三个地方。

  1. 一个是filter的group定义@Activate(group = {Constants.SERVER_KEY, Constants.CONSUMER}),这里这样定义后,就只有服务的消费者会生效,也就是事务的发起者,服务的调用方会进filter的invoke逻辑。
  2. 只有加@Hmily注解的方法或进事务处理逻辑,其他的方法直接跳过处理
  3. 最关键的是buildParticipant(hmilyTransactionContext, hmily, method, clazz, arguments, args)方法。dubbo的filter唯一的作用就是收集事务参与者信息并更新当前事务上线文信息。那么在事务协调时就能够从当前事务上线文里面获取到需要协调的事务参与者信息了。

参数者事务处理器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable {
    HmilyTransaction hmilyTransaction = null;
    HmilyTransaction currentTransaction;
    switch (HmilyActionEnum.acquireByCode(context.getAction())) {
        case TRYING:
            try {
                hmilyTransaction = hmilyTransactionExecutor.beginParticipant(context, point);
                final Object proceed = point.proceed();
                hmilyTransaction.setStatus(HmilyActionEnum.TRYING.getCode());
                //update log status to try
                hmilyTransactionExecutor.updateStatus(hmilyTransaction);
                return proceed;
            } catch (Throwable throwable) {
                //if exception ,delete log.
                hmilyTransactionExecutor.deleteTransaction(hmilyTransaction);
                throw throwable;
            } finally {
               HmilyTransactionContextLocal.getInstance().remove();
            }
        case CONFIRMING:
            currentTransaction = HmilyTransactionCacheManager.getInstance().getTccTransaction(context.getTransId());
            hmilyTransactionExecutor.confirm(currentTransaction);
            break;
        case CANCELING:
            currentTransaction = HmilyTransactionCacheManager.getInstance().getTccTransaction(context.getTransId());
            hmilyTransactionExecutor.cancel(currentTransaction);
            break;
        default:
            break;
    }
    Method method = ((MethodSignature) (point.getSignature())).getMethod();
    logger.error(HmilyActionEnum.acquireByCode(context.getAction()).getDesc());

    return DefaultValueUtils.getDefaultValue(method.getReturnType());
}

参与者事务处理器的逻辑比启动事务处理器要简单很多,try阶段记录事务日志用于事务补偿的时候使用。其他的confirm和cancel都是由启动事务管理器来触发调用执行的。这个地方之前纠结了楼主几个小时,怎么一个环绕织入的切面会被触发执行两次,其实是启动事务处理器里的confirm或cancel触发的。

disruptor+ScheduledService处理事务日志,补偿处理失败的事务

这个不细聊了,简述下。disruptor是一个高性能的队列。对事务日志落地的所有操作都是通过disruptor来异步完成的。ScheduledService默认128秒执行一次,来检查是否有处理失败的事务日志,用于补偿事务协调失败的事务

文末结语

相比较2pc的LCN而言,tcc分布式事务对业务侵入性更高。也因2pc的长时间占用事务资源,tcc的性能肯定比2pc要好。两者之间本身不存在谁优谁劣的问题。所以在做分布式事务选型时,选一个对的适合自身业务的分布式事务框架就比较重要了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Hmily:高性能异步分布式事务TCC框架
github: https://github.com/yu199195/hmily
kirito-moe
2019/11/05
8730
Hmily:高性能异步分布式事务TCC框架
Hmily框架特性[https://github.com/yu199195/hmily]
芋道源码
2019/10/29
1.1K0
Hmily:高性能异步分布式事务TCC框架
分布式事务 TCC-Transaction 源码分析 —— TCC 实现
本文主要基于 TCC-Transaction 1.2.3.3 正式版 1. 概述 2. TCC 原理 3. TCC-Transaction 原理 4. 事务与参与者 4.1 事务 4.2 参与者 5. 事务管理器 5.1 发起根事务 5.2 传播发起分支事务 5.3 传播获取分支事务 5.4 提交事务 5.5 回滚事务 5.6 添加参与者到事务 6. 事务拦截器 6.1 Compensable 6.2 可补偿事务拦截器 6.3 资源协调者拦截器 666. 彩蛋 ---- 1. 概述 本文分享 TCC 实现
芋道源码
2018/03/02
5.2K0
分布式事务 TCC-Transaction 源码分析 —— TCC 实现
Hmily(3)
5. 提供端的方法也需要Hmily注解,当然也会有确认取消方法,执行切面方法DubboHmilyTransactionInterceptor#interceptor这个时候的context不会为空,转成对象HmilyTransactionContext,HmilyTransactionAspectServiceImpl#invoke找出合适的处理类HmilyTransactionFactoryServiceImpl#factoryOf即ParticipantHmilyTransactionHandler
全栈程序员站长
2022/08/25
2060
Hmily(1)
1. Hmily是个高性能异步分布式事务TCC框架,具体包含Spring AOP,Disruptor,Dubbo等框架,当然还有其他的RPC框架。源码在https://github.com/yu199195/hmily,本文以duubo调用,mysql存储事务日志,kryo序列化为主,主要以下单支付减库存减余额为例,注解为Hmily,确认方法,取消方法和本次的tyr操作方法参数应该保持一致。前两个方法名配置在注解上。
全栈程序员站长
2022/08/31
3680
分布式事务之TCC事务模型
在上篇文章《老生常谈——利用消息队列处理分布式事务》一文中留了一个坑,今天来填坑。如下图所示
用户6884826
2021/07/08
1.3K0
TCC 分布式事务解决方案
TCC 是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与 Try或者 Commit相反的操作即回滚操作。TM首先发起所有的分支事务的 try操作,任何一个分支事务的 try操作执行失败,TM将会发起所有分支事务的 Cancel操作,若 Try操作全部成功,TM将会发起所有分支事务的 Confirm操作,其中 Confirm/Cancel 操作若执行失败,TM会进行重试。
Java架构师必看
2021/05/14
1.2K0
TCC 分布式事务解决方案
分布式事务框架 seata-golang 接入指南
seata-golang 是一个分布式事务框架,实现了 AT 模式和 TCC 模式,AT 模式相较 TCC 模式对代码的入侵性更小、需要开发的接口更少;但 AT 模式对事务操作的数据持有全局锁,从这点来说,TCC 模式性能更好。
CNCF
2021/03/15
3.3K0
分布式事务框架 seata-golang 接入指南
分布式事务TCC(Hmily)
TCC是Try、Confirm、Cancel三个词语,TCC分布式事务的三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作业务检查以及资源预留,Confirm做业务确认操作,Cancel实现一个月try相反的操作即为回滚操作。Try操作全部成功,TM将会发起所有分支事务的Confirm操作,如Confirm/Cancel操作失败,TM进行重试。
全栈程序员站长
2022/08/31
6530
分布式事务TCC(Hmily)
分布式事务-TCC(Hmily)[通俗易懂]
TCC是什么: TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认 Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的 操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所 有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel 操作若执行失败,TM会进行重试。 分布式事务执行成功:
全栈程序员站长
2022/08/31
8060
分布式事务-TCC(Hmily)[通俗易懂]
分布式事务之解决方案(TCC)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
海仔
2019/12/03
6.3K0
分布式事务解决方案之TCC(Hmily)「建议收藏」
TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。
全栈程序员站长
2022/08/26
3.6K0
分布式事务解决方案之TCC(Hmily)「建议收藏」
分布式事务-04:TCC实现过程及原理
前面我们讲了分布式事务的基本概念,CAP理论等,也讲了2pc协议,3pc协议,我们可以暂时认为2pc协议,3pc协议他们是传统的事务处理机制,这一篇,我们讲一讲TCC(Try-Confirm-Cancel) 事务机制,相对于传统事务机制(X/Open XA Two-Phase-Commit),TCC的特别之处在于它不依赖资源管理器(RM)对XA的支持,而是通过对业务逻辑(由业务系统提供的)的调度来实现分布式事务。
IT云清
2022/05/07
1.3K0
分布式事务之TCC模式
在写一篇之前说一下TCC模型,即try confirm cancel(尝试---->提交---->回滚),tcc模型是一个非常典型的2pc(二阶段)提交,所谓的两个阶段是指:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)。
简单的程序员
2020/04/20
1.1K0
分布式事务之TCC模式
分布式事务(四)之TCC
在电商领域等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于CAP理论以及BASE理论,有人就提出了柔性事务的概念。在业内,关于柔性事务,最主要的有以下四种类型:两阶段型、补偿型、异步确保型、最大努力通知型几种。我们前边讲过的2PC和3PC都属于两阶段型,两阶段型事务存在长期锁定资源的情况,导致可用性差。接下来我们来介绍的TCC则是补偿型分布式事务。
玖柒的小窝
2021/11/07
5270
分布式事务(四)之TCC
关于如何实现一个TCC分布式事务框架的一点思考
一个TCC事务框架需要解决的当然是分布式事务的管理。关于TCC事务机制的介绍,可以参考TCC事务机制简介。
芋道源码
2018/10/26
1.1K0
分布式事务实战
微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发,从而被越来越多的开发者和公司推崇运用。但系统微服务化后,一个看似简单的功能,内部可能需要调用多个服务并操作多个数据库实现,服务调用的分布式事务问题变的非常突出,几乎可以说是无法避免。
yuanyi928
2019/12/19
8290
分布式事务实战
【分布式事务】GitHub上分布式事务框架压测性能对比
随着项目逐步以微服务开发为趋势,逐渐呈现一个服务对应一个数据库。从中产生了分布式事务的问题:一个操作先后调用不同的服务,要保证服务间的事务一致性,这就是分布式事务解决的问题。
全栈程序员站长
2022/11/01
5040
服务化带来的数据一致问题---分布式事务,事务型消息
本文我们聊聊分布式事务和事务型消息的解决思路,通过阅读本文,可以理解分布式事务和事务型消息,并且能够应用到实际生产工作中。
用户7927337
2020/11/04
2.2K0
服务化带来的数据一致问题---分布式事务,事务型消息
Seata实战-分布式事务简介及demo上手
Seata简介 Seata(Simple Extensible Autonomous Transaction Architecture) 是 阿里巴巴开源的分布式事务中间件,以高效并且对业务 0 侵入的方式,解决微服务场景下面临的分布式事务问题。
爱撸猫的杰
2021/03/04
1.5K0
相关推荐
Hmily:高性能异步分布式事务TCC框架
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验