Springboot dubbo @Service @Transactional 无法提供服务或者无法提供事务的解决办法

38 篇文章 1 订阅
5 篇文章 0 订阅

问题场景:

今天在springboot中集成spring事务的时候,遇到了一个大坑。如果(springboot+dubbo)中添加 @Service、@Transactional 两个注解的时候,就不能进行dubbo服务注册了。

解决历程:

1,先是在springboot启动类添加注解@EnableTransactionManagement,在对应的服务实现类上添加@Transactional。然后发现不能正常发布dubbo服务了,没有报错,但dubbo-admin就是没有收到服务注册。搜索一下,发现dubbo版本低,老版本不支持注解的事务,于是提高到dubbo2.6.2版本。

启动类:

服务类:

2,提高版本到dubbo2.6.2后,还是不行,又搜索一下,发现springboot的事务需要我们打开aop才可以,springboot开启aop需要添加aop相关的依赖,然后再在启动类中添加@EnableAspectJAutoProxy注解就可以开启aop功能了。然后我们还需要在application.yml添加spring.aop.proxy-target-class=true,试了试,可以了,但是消费端说找不到服务,腚眼一看,发现dubbo-admin里的服务是个代理(org.springframework.aop.SpringProxy)。

启动类中添加@EnableAspectJAutoProxy注释:

application.yml配置:

aop依赖:

<!--springboot上面添加aop-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

3,虽然能提供服务,但不能被消费者找到,继续搜索,需要在具体实现类里的@Service上添加(version = "1.0.0",interfaceClass=*.class),才可以,需要将接口的类名写入,才可以在dubbo-admin里正常展现服务接口,然后调用,可以做到事务回滚了。

服务提供方:

服务消费方:

注意:

1,首先提升dubbo的版本到2.6以后,再就是需要明确接口名称。

2,好多文章说要么注解实现dubbo,配置文件实现Transactional;要么注解实现Transactional,配置文件实现dubbo,不能同时注解两个,应该是老版本原因,现在可以同时支持了。

高能预警:

springboot+dubbo比较坑的是需要实现io.dubbo.springboot依赖,但是io.dubbo.springboot中包含的dubbo是dubbo:2.5.3,而且没有高版本的dubbo依赖了,那怎么办呢。。。。纠结了一下午,突然想到一个方案,然后顺利的解决这个问题了。

解决方案:

我们可以通过exclusions去除io.dubbo.springboot中的dubbo:2.5.3,然后再重新添加dubbo:2.6.2依赖就可以了。如果大家觉得这样就已经解决的话,那就大错特错了,因为你们会出现如下的错误:

1.java.lang.NoClassDefFoundError: org/I0Itec/zkclient/IZkStateListener

2.java.lang.NoClassDefFoundError: org/apache/zookeeper/Watcher$Event$KeeperState

3.java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy

大家从报错的信息就可以看出来,是缺少对应的依赖,我们只要添加对应的依赖就可以了。

<!--spring-boot-dubbo依赖-->

<dependency>

<groupId>io.dubbo.springboot</groupId>

<artifactId>spring-boot-starter-dubbo</artifactId>

<version>1.0.0</version>

<exclusions>

<!--去除com.alibaba依赖-->

<exclusion>

<groupId>com.alibaba</groupId>

<artifactId>dubbo</artifactId>

</exclusion>

</exclusions>

</dependency>

 

<!--添加2.6.2的dubbo依赖-->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>dubbo</artifactId>

<version>2.6.2</version>

</dependency>

 

<!--zookeeper客户端相关的curator依赖-->

<dependency>

<groupId>org.apache.curator</groupId>

<artifactId>curator-framework</artifactId>

<version>2.8.0</version>

</dependency>

 

<!--添加zookeeper依赖-->

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

<version>3.4.5</version>

</dependency>

dubbo全部的配置文件:

这样一波三折之后终于解决@Service、@Transactional 同时存在时候,无法提供服务或者无法提供事务的问题了。真的简直坑的一批,这种依赖,配置相关的问题是最恶心的,因为它不会报错,所以需要从方方面面猜测问题的原因才可以,不过虽然很坑,但是还好问题得到解决。

想要更多干货、技术猛料的孩子,快点拿起手机扫码关注我,我在这里等你哦~

                                                       

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
在分布式系统中,实现同步回滚事务通常需要使用分布式事务管理器,例如Atomikos、Narayana等。在Dubbo中,可以使用Dubbo XA扩展来实现分布式事务Dubbo XA扩展是基于JTA规范的,它提供了一种在分布式环境下实现同步回滚事务的方式。具体实现方式如下: 1. 首先,需要在Dubbo服务提供者和消费者的配置文件中启用Dubbo XA扩展: ``` <dubbo:provider xa="true" /> <dubbo:consumer xa="true" /> ``` 2. 在Dubbo服务提供者中,需要使用`@Transactional`注解将服务方法标记为事务方法: ``` @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @Transactional public void addUser(User user) { userMapper.addUser(user); } } ``` 3. 在Dubbo服务消费者中,需要使用`TransactionContext`对象来实现同步回滚事务: ``` @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Reference(version = "1.0.0") private UserDubboService userDubboService; @Override @Transactional public void addUser(User user) { userMapper.addUser(user); // 同步回滚事务 TransactionContext transactionContext = DubboTransactionContext.getContext(); transactionContext.setXid(XidUtils.generateXid()); transactionContext.setAttachment("user", user); try { userDubboService.addUser(user); transactionContext.setStatus(TransactionContext.Status.COMMITTING); } catch (Exception e) { transactionContext.setStatus(TransactionContext.Status.ROLLBACKING); throw e; } } } ``` 在消费者调用`userDubboService.addUser(user)`之前,需要先设置`TransactionContext`对象的XID和附加属性。如果调用成功,将`TransactionContext`对象的状态设置为COMMITTING,否则将状态设置为ROLLBACKING。 通过以上步骤,就可以实现Dubbo调用中的同步回滚事务了。需要注意的是,Dubbo XA扩展仅支持同步回滚事务,不支持异步回滚。如果需要异步回滚,可以考虑使用TCC或MQ等方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值