apache / incubator-seata

:fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.
https://seata.apache.org/
Apache License 2.0
25.23k stars 8.76k forks source link

springboot dubbo TCC @Reference #2194

Closed LayGit closed 4 years ago

LayGit commented 4 years ago

问题一

在开启 GlobalTransactional 的服务中使用 Reference 引用了 TCC 服务,但是 TCC 服务一阶段方法中的 BusinessActionContext 始终为 null,也始终收不到二阶段提交的消息。跟踪发现 wrapIfNecessary 遍历的 Bean 中并没有该服务。需要在 Configuration 中使用 ReferenceBean 显式引用 dubbo 服务,然后在 GlobalTransactional 的方法中使用 Autowired 引入的 TCC 服务,才可以正常使用。

不可用

    @Reference(version="1.0.0")
    TccActionOne tccActionOne;

    @Reference(version="1.0.0")
    TccActionTwo tccActionTwo;

    @GlobalTransactional
    @Override
    public String test() {
        boolean result1 = tccActionOne.prepare(null, 1);
        boolean result2 = tccActionTwo.prepare(null, "a");
        return "success";
    }

调整后可用

@Configuration
public class ReferenceConfig {
    @Bean
    public ReferenceBean<TccActionOne> tccActionOne() {
        ReferenceBean<TccActionOne> ref = new ReferenceBean<>();
        ref.setVersion("1.0.0");
        ref.setInterface(TccActionOne.class);
        ref.setTimeout(5000);
        ref.setCheck(false);
        return ref;
    }

    @Bean
    public ReferenceBean<TccActionTwo> tccActionTwo() {
        ReferenceBean<TccActionTwo> ref = new ReferenceBean<>();
        ref.setVersion("1.0.0");
        ref.setInterface(TccActionTwo.class);
        ref.setTimeout(5000);
        ref.setCheck(false);
        return ref;
    }
}
    @Autowired
    TccActionOne tccActionOne;

    @Autowired
    TccActionTwo tccActionTwo;

    @GlobalTransactional
    @Override
    public String test() {
        boolean result1 = tccActionOne.prepare(null, 1);
        boolean result2 = tccActionTwo.prepare(null, "a");
        return "success";
    }

主要依赖: springboot 2.2.1.RELEASE dubbo-spring-boot-starter 2.7.5 seata-spring-boot-starter 1.0.0

问题二

如果使用 dubbo-springboot-starter 2.7.4.1 版本,会有一个错误 Duplicate extension org.apache.dubbo.rpc.Filter name transactionpropagation on io.seata.integration.dubbo.TransactionPropagationFilter and io.seata.integration.dubbo.alibaba.TransactionPropagationFilter, dubbo version: 2.7.4.1

zjinlei commented 4 years ago

refer https://github.com/seata/seata/pull/1816

zhangthen commented 4 years ago

目前 基于注解的 TCC 服务自动代理还不支持,我们会尽快安排开发,谢谢反馈!

q294881866 commented 4 years ago

在跟进这个问题,进展会尽快同步。

zhangthen commented 4 years ago

在跟进这个问题,进展会尽快同步。

赞,后面麻烦跟进一下这个问题~

funky-eyes commented 4 years ago

关于问题2,我使用的是

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.4.1</version>
        </dependency>

目前看起来一切正常,请问复现过程能否提供一下

funky-eyes commented 4 years ago

对于问题2:https://github.com/seata/seata-samples/tree/master/dubbo-multiple-datasource-mybatis-plus 这是官方的一个dubbo2.7.4.1的示例,可以试着跑跑看,最好可以提供下您的复现过程

funky-eyes commented 4 years ago

初步排查,发现是2.7.4.1的源码中,dubbo在加载扩展类时会进行缓存这个扩展类,由于seata同时包含了alibaba版跟apache版,造成了同个扩展类名下,dubbo加载扩展类时会进从缓存里判断是否已存在,而因为类名相同,导致缓存里读出的是不同的class,这时候因为当前需要加载的扩展类与缓存存储的class不同,dubbo会抛出异常捕获并处理,2.7.3是这样做的,但是2.7.4.1时加入了把这个异常打印出来的情况,所以出现了问题2,上诉问题会提交反馈给dubbo社区,感谢您的反馈