Seata中的TCC模式学习一

简介: Seata中的TCC模式学习一

由于我们的客户中心发送线索、整车订单服务配车、整车财务服务财务信息推送中都使用的全局事务是基于@GlobalTransactional、@TwoPhaseBusinessAction,因此有必要了解这两个注解中是如何在分布式事务中发挥作用的,也即TCC的实现。虽然AT模式比TCC模式要好。

一、TCC实现模式的分类

资源预留模式
补偿模式

1)资源预留模式

在第一阶段预先留下资源,从而来保证第二阶段的执行。

比如在财务中,第一阶段将要支付的金额进行冻结,也即中间状态。在第二阶段如果是提交,则进行金额扣减,从而账号金额发生变化。如果是回滚,则将冻结进行取消,从而保证金额不会发生变化。

此时:

try阶段:完成业务检查,和预留好资源

confirm阶段:基于try执行真正的业务逻辑

cancel阶段:释放预留的资源

2)补偿模式

在实际业务中,补偿模式要用得多一些。比如下订单、减库存的时候,就会用到。

比如:下订单的时候,首先进行一个插入操作,减库存的第一阶段减少库存,并记录库存减少的数量。

第二阶段,如果是全局提交,则不用做什么,只需要将第一阶段记录的信息进行删除即可。如果是全局回滚,则进行补偿,将扣减的库存还回来即可。

此时:

try阶段: 执行真正的业务逻辑

confirm阶段: 将额外的记录信息删除即可

cancel阶段: 根据额外的记录信息对try发生失败进行补偿

二、Seata中,业务系统注解的增强

和AT模式一样,TCC模式的事务的发起方都是需要添加@GlobalTransactional这个注解的。因此我们可以看着这里有两个拦截器值得我们去关注,TccActionInterceptor与GlobalTransactionalInterceptor全局事务拦截器。因为它们是进行业务系统分布式事务增强的源头。

TCC模式的实现可以根据注解TwoPhaseBusinessAction找到对应的拦截器TccActionInterceptor。从而进一步找到

TccActionInterceptor implements MethodInterceptor, ConfigurationChangeListener, Ordered

在往上看,可以看到其是基于AOP实现的增强:

GlobalTransactionScanner extends AbstractAutoProxyCreator
        implements ConfigurationChangeListener, InitializingBean, ApplicationContextAware, DisposableBean {

因为其实现了AbstractAutoProxyCreator抽象自动代理创建器和InitializingBean、ApplicationContextAware。因此我们可以看到它的重要方法:wrapIfNecessary。这个如果看过Spring的AOP源码的话,就会知道这个方法是进行AOP增强的必经之路。

if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, applicationContext)) {
                    // init tcc fence clean task if enable useTccFence
                    TCCBeanParserUtils.initTccFenceCleanTask(TCCBeanParserUtils.getRemotingDesc(beanName), applicationContext);
                    //TCC interceptor, proxy bean of sofa:reference/dubbo:reference, and LocalTCC
                    interceptor = new TccActionInterceptor(TCCBeanParserUtils.getRemotingDesc(beanName));
                    ConfigurationCache.addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
                            (ConfigurationChangeListener)interceptor);
                }else {
                   //接口和实现都能够找到拦截器,进行全局事务拦截
                    Class<?> serviceInterface = SpringProxyUtils.findTargetClass(bean);
                    Class<?>[] interfacesIfJdk = SpringProxyUtils.findInterfaces(bean);
                    if (!existsAnnotation(serviceInterface)
                            && !existsAnnotation(interfacesIfJdk)) {
                        return bean;
                    }
                    if (globalTransactionalInterceptor == null) {
                        globalTransactionalInterceptor = new GlobalTransactionalInterceptor(failureHandlerHook);
                        ConfigurationCache.addConfigListener(
                                ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
                                (ConfigurationChangeListener)globalTransactionalInterceptor);
                    }
                    interceptor = globalTransactionalInterceptor;
                }
                 //进行aop的增强
                if (!AopUtils.isAopProxy(bean)) {
                    bean = super.wrapIfNecessary(bean, beanName, cacheKey);
                } else {
                    AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);
                    Advisor[] advisor = buildAdvisors(beanName, getAdvicesAndAdvisorsForBean(null, null, null));
                    int pos;
                    for (Advisor avr : advisor) {
                        // Find the position based on the advisor's order, and add to advisors by pos
                        pos = findAddSeataAdvisorPosition(advised, avr);
                        advised.addAdvisor(pos, avr);
                    }
                }
                PROXYED_SET.add(beanName);
                return bean;
            }

是否是TCC自动代理,如果是则初始化TCC清理Task,同时创建TCCActionInterceptor对象,添加到配置缓存中,以便可以扫描到带有TwoPhaseBusinessAction的class。

同时我们注意到其实TCC和AT模式一样,事务的发起方都是需要添加@GlobalTransactional这个注解的。因此还有一个拦截器GlobalTransactionalInterceptor全局事务拦截器。

下一篇我们来看看,TccActionInterceptor和GlobalTransactionalInterceptor都做了哪些事情。因为它们必须要和两个注解建立联系,才能发挥作用。

目录
相关文章
|
30天前
|
数据库 微服务
SEATA模式
Seata 是一款开源的分布式事务解决方案,支持多种事务模式以适应不同的应用场景。其主要模式包括:AT(TCC)模式,事务分三阶段执行;TCC 模式,提供更灵活的事务控制;SAGA 模式,基于状态机实现跨服务的事务一致性;XA 模式,采用传统两阶段提交协议确保数据一致性。
43 5
|
2月前
Seata框架在AT模式下是如何保证数据一致性的?
通过以上这些机制的协同作用,Seata 在 AT 模式下能够有效地保证数据的一致性,确保分布式事务的可靠执行。你还可以进一步深入研究 Seata 的具体实现细节,以更好地理解其数据一致性保障的原理。
41 3
|
7月前
|
Apache 开发者
Apache Seata 如何解决 TCC 模式的幂等、悬挂和空回滚问题
【6月更文挑战第8天】Apache Seata 是一款分布式事务框架,解决TCC模式下的幂等、悬挂和空回滚问题。通过记录事务状态处理幂等,设置超时机制避免悬挂,明确标记Try操作成功来处理空回滚。Seata 提供丰富配置和管理功能,确保分布式事务的可靠性和效率,支持复杂事务处理场景,为企业业务发展提供支持。
248 7
|
8月前
|
NoSQL Java 数据库
Seata常见问题之xa模式下插入一条数据再更新这条数据会报错如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
209 2
|
8月前
|
Java 关系型数据库 微服务
Seata常见问题之项目一直启动不成功如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
618 0
|
2月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
1天前
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
14 1
|
26天前
|
消息中间件 SQL 中间件
大厂都在用的分布式事务方案,Seata+RocketMQ带你打破10万QPS瓶颈
分布式事务涉及跨多个数据库或服务的操作,确保数据一致性。本地事务通过数据库直接支持ACID特性,而分布式事务则需解决跨服务协调难、高并发压力及性能与一致性权衡等问题。常见的解决方案包括两阶段提交(2PC)、Seata提供的AT和TCC模式、以及基于消息队列的最终一致性方案。这些方法各有优劣,适用于不同业务场景,选择合适的方案需综合考虑业务需求、系统规模和技术团队能力。
182 7
|
2月前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
85 6
|
2月前
|
数据库
如何在Seata框架中配置分布式事务的隔离级别?
总的来说,配置分布式事务的隔离级别是实现分布式事务管理的重要环节之一,需要认真对待和仔细调整,以满足业务的需求和性能要求。你还可以进一步深入研究和实践 Seata 框架的配置和使用,以更好地应对各种分布式事务场景的挑战。
43 6