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)
  • 相关阅读:
    HDU_1846 Brave Game(sg函数简化版)
    POJ 3225 Help with Intervals(线段树)
    ZOJ_3501 Roman Order
    HDU_1527 取石子游戏(威佐夫博弈)
    HDU_2112 HDU Today(DIjkstra + map映射)
    HDU_3339 In Action(Dijkstra + DP)
    单链表的实现(课本上的算法)
    haproxy 基于 uri 实现调度
    haproxy 基于 cookie 实现 session 绑定
    [转]ASP.NET 虚拟主机安全漏洞解决方案
  • 原文地址:https://www.cnblogs.com/pengpengdeyuan/p/12737585.html
Copyright © 2011-2022 走看看