@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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM