seata的xid在feign中传递分析

概述

业务中经常会遇到分布式事务失效的场景;通常情况下分析下两边的xid是否一致,就可以初步判定原因;
我这边正好遇到openfeign调用时其中一个rm抛异常,其他rm没回滚的现象;

排查了下发现tm和第一个rm注册到seataxid就不通;
然后看了下相关代码,发现openfeign的拦截器中没有对xid进行传递,后续传递xid之后,分布式事务后面回滚就ok了;

当前环境
jdk:1.8
seata-spring-boot-starter:1.6.1
spring-cloud-dependencies:2021.0.5
spring-cloud-alibaba-dependencies:2021.0.5.0

解决方案

在feign拦截器中传递seata的xid

package com.xxx.xxx.xxx.config;

import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.seata.core.context.RootContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;


@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor requestInterceptor() {
        // 添加拦截器,所有内部服务调用都带上token
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                
                //feign seata xid传递
                seataHeadProcess(requestTemplate);
            }
        };
    }


    /**
     * 传递seata的全局xid
     */
    private void seataHeadProcess(RequestTemplate requestTemplate){
        // 从 seata 的 RootContext 中获取当前 XID
        String xid = RootContext.getXID();
        if (StrUtil.isBlank(xid)) return;

        requestTemplate.header(RootContext.KEY_XID, xid);
    }
}

源码分析

一般springboot中的先找xxxAutoConfiguration
然后在SeataAutoConfiguration的同级目录下发现了SeataHttpAutoConfiguration,就是这个了;

然后一路点进去,最后发现在
io.seata.integration.http.TransactionPropagationInterceptor
中就看到了关于http请求头中xid的相关处理

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值