@Transactional使用常见报错解决及注入错误

一个项目中,避免不了使用事务,而在Springboot项目中,我们一般使用@Transactional注解来设置事务控制,@Transactional的详情使用可见博客https://www.cnblogs.com/pengpengdeyuan/p/12737891.html

在加完@Transactional注解启动项目时,可能会出现以下报错

Description:

The bean 'testService' could not be injected as a 'com.xxx.xxx.service.impl.TestService' because it is a JDK dynamic proxy that implements:
    com.pk.kxl.service.ITestService


Action:

Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.

这类情况主要是jdk自动代理与CGlib代理的注入方式差异造成的。

一、查看是否开启事务支持

首先查看项目是否是SpringBoot项目,SpringBoot项目会自动开启事务支持。

二、查看注入方式

从错误信息中可以看出,它是在我的Controller层中,注入testService这个Bean时失败,(失败的原因就是我导入的是接口实现,而springboot的事务默认是使用jdk的动态代理,是基于接口进行注入的)。意思就是我注入的是service层的实现类,这种操作是非法的,改成注入service层接口就可以解决。

 

这时可以想到,既然jdk动态代理不行,那我们就改成CGlib动态代理(基于类,即设置proxyTargetClass=True在启动事务管理上、、、@EnableTransactionManagement(proxyTargetClass=True)),此时需要引入相应的cglib库的jar包,在springboot中已经集成了。但在spring3.2之前是需要引入的。

@SpringBootApplication
//启用事务管理(可省略)
@EnableTransactionManagement(proxyTargetClass=True)

 

第三种方式就可以使用@Scop注解去解决,他会将所有方法上的事务都强制改为是CGLib方式代理的。

方法:在service层上添加一个注解 @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

@Service
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

 

posted @ 2020-04-20 14:28  砰砰的猿  阅读(4354)  评论(0编辑  收藏  举报