zoukankan      html  css  js  c++  java
  • @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)
  • 相关阅读:
    bzoj3505 数三角形 组合计数
    cogs2057 殉国 扩展欧几里得
    cogs333 荒岛野人 扩展欧几里得
    bzoj1123 BLO tarjan求点双连通分量
    poj3352 road construction tarjan求双连通分量
    cogs1804 联合权值 dp
    cogs2478 简单的最近公共祖先 树形dp
    cogs1493 递推关系 矩阵
    cogs2557 天天爱跑步 LCA
    hdu4738 Caocao's Bridge Tarjan求割边
  • 原文地址:https://www.cnblogs.com/pengpengdeyuan/p/12737585.html
Copyright © 2011-2022 走看看