[seata]Question: Seata与Dubbo整合如何开启TCC自动代理?

2023-12-09 9 views
6

问题描述

我使用Seata与Dubbo整合的demo,在阅读Seata文档的时候看到如果Seata和Dubbo配合使用无需使用@LocalTCC注解。

@LocalTCC注解用来表示实现了二阶段提交的本地的TCC接口。如果使用Dubbo作为RPC通信组件则无须用此注解。

但是当我去除掉@LocalTCC的时候则发现无法进行代理。

追踪源码发现在GlobalTransactionScanner.wrapIfNecessary方法中TCCBeanParserUtils.isTccAutoProxy(bean, beanName, applicationContext)并没有为true

在其中发现DubboRemotingParser.isReferenceisRemotingFactoryBean中调用的!SpringProxyUtils.isProxy(bean)均没有识别到代理

请问应该如何进行配置才能使用Dubbo的TCC自动代理呢?

回答

6

一、Code

1、公共包定义RPC接口

public interface IOrderService {

    @TwoPhaseBusinessAction(name = "createOrder", commitMethod = "commitOrder", rollbackMethod = "rollBackOrder", useTCCFence = true)
    String createOrder(BusinessActionContext businessActionContext, @BusinessActionContextParameter(paramName = "order") Order order);

    /**
     * 由TC发起调用的提交
     *
     * @param businessActionContext 上下文
     * @return 成功或失败
     */
    boolean commitOrder(BusinessActionContext businessActionContext);

    /**
     * 由TC发起调用的回滚
     *
     * @param businessActionContext 上下文
     * @return 成功或失败
     */
    boolean rollBackOrder(BusinessActionContext businessActionContext);
}
public interface IPolicyService {

    @TwoPhaseBusinessAction(name = "createPolicy", commitMethod = "commitPolicy", rollbackMethod = "rollBackPolicy", useTCCFence = true)
    String createPolicy(BusinessActionContext businessActionContext, @BusinessActionContextParameter(paramName = "policy") Policy policy);

    /**
     * 由TC发起调用的提交
     *
     * @param businessActionContext 上下文
     * @return 成功或失败
     */
    boolean commitPolicy(BusinessActionContext businessActionContext);

    /**
     * 由TC发起调用的回滚
     *
     * @param businessActionContext 上下文
     * @return 成功或失败
     */
    boolean rollBackPolicy(BusinessActionContext businessActionContext);
}

2、Order服务实现

import com.alibaba.fastjson2.JSONObject;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Slf4j
@DubboService(interfaceClass = IOrderService.class)
@RequiredArgsConstructor
public class OrderService implements IOrderService {
    //......
}

3、Policy服务实现

import com.alibaba.fastjson2.JSONObject;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;
import java.util.UUID;

@Slf4j
@DubboService(interfaceClass = IPolicyService.class)
@RequiredArgsConstructor
public class PolicyService implements IPolicyService {
    //....
}

4、使用者

import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@RequiredArgsConstructor
public class ProductService implements IProductService {

    @DubboReference(interfaceClass = IPolicyService.class)
    private final IPolicyService policyService;

    @DubboReference(interfaceClass = IOrderService.class)
    private final IOrderService orderService;

    private final ProductMapper productMapper;

}

二、尝试

在看过源码后,尝试使用了注入ReferenceBean的方式开启,但未成功

@Configuration
public class Config {

    @Bean
    @DubboReference(interfaceClass = IOrderService.class)
    public ReferenceBean<IOrderService> orderService() {
        return new ReferenceBean();
    }

    @Bean
    @DubboReference(interfaceClass = IPolicyService.class)
    public ReferenceBean<IPolicyService> policyService() {
        return new ReferenceBean();
    }

}

可能是缺了什么配置,没有找到相关描述

5

1.3.0版本后支持org.apache.dubbo.config.annotation.Reference。