@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)
分享所感,如有侵权,请联系删除,可扫码关注微信公众号获取更多福利噢。
本文仅限于技术交流,若造成不良影响,本文创作人员概不负责,请支持正版应用,注重产权保护!!
(您的“打赏”将是我最大的写作动力!转载请注明出处.)
本文仅限于技术交流,若造成不良影响,本文创作人员概不负责,请支持正版应用,注重产权保护!!
(您的“打赏”将是我最大的写作动力!转载请注明出处.)
关注微信公众号 |