带你读《Apache Dubbo微服务开发从入门到精通》——二、 分布式事务

简介: 带你读《Apache Dubbo微服务开发从入门到精通》——二、 分布式事务

二、 分布式事务

 

1. 使用方式与概念

 

1) 事务上下文

 

Seata的事务上下文由RootContext来管理。

 

应用开启一个全局事务后,RootContext会自动绑定该事务的XID,事务结束(提交或回滚完成),RootContext会自动解绑XID。

 

image.png 

 

应用可以通过RootContext的API接口来获取当前运行时的全局事务XID。

 

image.png

 

应用是否运行在一个全局事务的上下文中,就是通过RootContext是否绑定XID来判定的。

 

image.png

 

2) 事务传播

 

Seata全局事务的传播机制就是指事务上下文的传播,根本上,就是XID的应用运行时的传播方式。

 

服务内部的事务传播

 

默认的,RootContext的实现是基于ThreadLocal的,即XID绑定在当前线程上下文中。

 

image.png

 

所以服务内部的XID传播通常是天然的通过同一个线程的调用链路串连起来的。默认不做任何处理,事务的上下文就是传播下去的。

 

如果希望挂起事务上下文,则需要通过RootContext提供的API来实现:

 

image.png

 

跨服务调用的事务传播

 

通过上述基本原理,我们可以很容易理解:

 

注:

跨服务调用场景下的事务传播,本质上就是要把XID通过服务调用传递到服务提供方,并绑定到RootContext中去。

 

只要能做到这点,理论上Seata可以支持任意的微服务框架。

 

2. 完整示例

 

完整示例请参见Dubbo给的官方示例https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-seata

 

3. 对Dubbo支持的解读

 

下面,我们通过内置的对Dubbo RPC支持机制的解读,来说明Seata在实现对一个特定微服务框架支持的机制。

 

对Dubbo的支持,我们利用了Dubbo框架的_org.apache.dubbo.rpc.Filter_机制。

 

/**
 * The type Transaction propagation filter.
 */
@Activate(group = { Constants.PROVIDER, Constants.CONSUMER }, order = 100)
public class TransactionPropagationFilter implements Filter {
    private static final Logger LOGGER = LoggerFactory.getLogger(TransactionPropagationFilter.class);
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        String xid = RootContext.getXID(); // 获取当前事务 XID
        String rpcXid = RpcContext.getContext().getAttachment(RootContext.KEY_XID); // 获取 RPC 调用传递过来的 XID
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("xid in RootContext[" + xid + "] xid in RpcContext[" + rpcXid + "]");
        }
        boolean bind = false;
        if (xid != null) { // Consumer:把 XID 置入 RPC 的 attachment 中
            RpcContext.getContext().setAttachment(RootContext.KEY_XID, xid);
        } else {
            if (rpcXid != null) { // Provider:把 RPC 调用传递来的 XID 绑定到当前运行时
                RootContext.bind(rpcXid);
                bind = true;
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("bind[" + rpcXid + "] to RootContext");
                }
            }
        }
        try {
            return invoker.invoke(invocation); // 业务方法的调用
        } finally {
            if (bind) { // Provider:调用完成后,对 XID 的清理
                String unbindXid = RootContext.unbind();
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("unbind[" + unbindXid + "] from RootContext");
                }
                if (!rpcXid.equalsIgnoreCase(unbindXid)) {
                    LOGGER.warn("xid in change during RPC from " + rpcXid + " to " + unbindXid);
                    if (unbindXid != null) { // 调用过程有新的事务上下文开启,则不能清除
                        RootContext.bind(unbindXid);
                        LOGGER.warn("bind [" + unbindXid + "] back to RootContext");
                    }
                }
            }
        }
    }
}


相关文章
|
3月前
|
消息中间件 监控 Java
Apache Kafka 分布式流处理平台技术详解与实践指南
本文档全面介绍 Apache Kafka 分布式流处理平台的核心概念、架构设计和实践应用。作为高吞吐量、低延迟的分布式消息系统,Kafka 已成为现代数据管道和流处理应用的事实标准。本文将深入探讨其生产者-消费者模型、主题分区机制、副本复制、流处理API等核心机制,帮助开发者构建可靠、可扩展的实时数据流处理系统。
405 4
|
运维 监控 负载均衡
探索微服务架构下的服务治理:动态服务管理平台深度解析
探索微服务架构下的服务治理:动态服务管理平台深度解析
|
运维 监控 安全
探索微服务架构下的服务治理:动态服务管理平台的力量
探索微服务架构下的服务治理:动态服务管理平台的力量
|
负载均衡 监控 Java
深入探索微服务架构下的服务治理
深入探索微服务架构下的服务治理
184 39
|
消息中间件 监控 数据可视化
Apache Airflow 开源最顶级的分布式工作流平台
Apache Airflow 是一个用于创作、调度和监控工作流的平台,通过将工作流定义为代码,实现更好的可维护性和协作性。Airflow 使用有向无环图(DAG)定义任务,支持动态生成、扩展和优雅的管道设计。其丰富的命令行工具和用户界面使得任务管理和监控更加便捷。适用于静态和缓慢变化的工作流,常用于数据处理。
Apache Airflow 开源最顶级的分布式工作流平台
|
存储 监控 负载均衡
构建高效微服务架构:服务治理与监控的实践
构建高效微服务架构:服务治理与监控的实践
|
负载均衡 Java 云计算
微服务架构下的服务治理与容错机制
微服务架构下的服务治理与容错机制
233 20
|
负载均衡 算法 Java
深入探索微服务架构下的服务治理
深入探索微服务架构下的服务治理
|
监控 安全 测试技术
深入理解并实践微服务架构中的服务治理
深入理解并实践微服务架构中的服务治理
574 1
|
运维 监控 Nacos
探索微服务架构下的服务治理:动态服务管理平台的力量
探索微服务架构下的服务治理:动态服务管理平台的力量

推荐镜像

更多