作者:Eddy  历史版本:1  最后编辑:龚清  更新时间:2024-11-20 15:41

编写版本:v3.5.3
适用版本:v3.5.3+

Seata事务集成

  1. Seata分布式事务的核心是全局控制,即全局锁(XID)机制,必须保证XID在每个服务中的传递
  2. 集成主要关注两个点:XID(全局锁)传递、数据源代理
  3. 更详细的内容请自行查阅Seata官方文档:http://seata.io/zh-cn/docs/overview/what-is-seata.html

XID(全局锁)传递

  1. Spring Cloud集成

    1. 首先确保你引入了spring-cloud-starter-alibaba-seata的依赖.

    2. com.alibaba.cloud.seata.web.SeataHandlerInterceptor已经自动封装调用方传递过来的xid

       @Override
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
               Object handler) {
           String xid = RootContext.getXID();// 从上下文获取
           String rpcXid = request.getHeader(RootContext.KEY_XID);// 从请求头获取
           if (log.isDebugEnabled()) {
               log.debug("xid in RootContext {} xid in RpcContext {}", xid, rpcXid);
           }
      
           if (StringUtils.isBlank(xid) && rpcXid != null) {
               RootContext.bind(rpcXid);// 绑定上下文,后续业务可以直接使用RootContext.getXID()
               if (log.isDebugEnabled()) {
                   log.debug("bind {} to RootContext", rpcXid);
               }
           }
      
           return true;
       }
    3. 如果xid还无法传递,请确认你是否实现了WebMvcConfigurer,如果是,请参考com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration#addInterceptors的方法.把SeataHandlerInterceptor加入到你的拦截链路中.

      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
      import org.springframework.boot.autoconfigure.web.ResourceProperties;
      import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration;
      import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.boot.context.properties.EnableConfigurationProperties;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Import;
      import org.springframework.core.annotation.Order;
      import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
      
      import com.alibaba.cloud.seata.web.SeataHandlerInterceptor;
      
      @Configuration(proxyBeanMethods = false)
      @ConfigurationProperties(prefix = "seata")
      @ConditionalOnProperty(prefix = "seata", name = "enable", havingValue = "true", matchIfMissing = false)
      @Import(EnableWebMvcConfiguration.class)// 重点
      @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })// 重点
      @Order(0)
      public class SeataConfigurer implements WebMvcConfigurer {// 重点
      
       private static final Logger LOGGER = LoggerFactory.getLogger(SeataConfigurer.class);
      
       public SeataConfigurer() {
           if (LOGGER.isInfoEnabled()) {
               LOGGER.info("{} init...", getClass().getSimpleName());
           }
       }
      
       @Override
       public void addInterceptors(InterceptorRegistry registry) {
           registry.addInterceptor(new SeataHandlerInterceptor()).addPathPatterns("/**");// 重点
       }
      
      }
  2. HttpClient集成
    手动设置请求头
    RootContext.KEY_XID// 请求头key
    RootContext.getXID()// 请求头值

     // IBPS中如何传递
     ApacheHttpClient.HearderBuilder.create()
                 .a(RootContext.KEY_XID, RootContext.getXID()).build()

数据源代理

seata:
  # 必须设置true,否则事务不生效
  enable-auto-data-source-proxy: true