• @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)
  • 相关阅读:
    jmeter实战
    安卓学习进度_11
    安卓学习进度_10
    安卓学习进度_9
    安卓学习进度_8
    安卓软件学习进度_7
    安卓学习进度_6
    安卓软件学习进度_5
    安卓软件学习进度_4
    安卓软件学习进度_3
  • 原文地址:https://www.cnblogs.com/pengpengdeyuan/p/12737585.html
Copyright © 2020-2023  润新知