javascript
wordpress外部调用到html_Spring 自调用事务失效,你是怎么解决的?
相信大家都遇到一種事務(wù)失效場(chǎng)景,那就是 Spring 自調(diào)用,就是在 Service 方法內(nèi),調(diào)用另一個(gè)加 @Transactional 注解的方法,發(fā)現(xiàn)事務(wù)失效,這時(shí)候你是怎么解決的呢?
公眾號(hào):『 劉志航 』,記錄工作學(xué)習(xí)中的技術(shù)、開(kāi)發(fā)及源碼筆記;時(shí)不時(shí)分享一些生活中的見(jiàn)聞感悟。歡迎大佬來(lái)指導(dǎo)!
事情回顧
那是一個(gè)我忘了天氣咋樣的下午,突然蹦出一個(gè)小紅點(diǎn),嗯~ 挺著急的小紅點(diǎn)。
原來(lái)是事務(wù)失效了!
莫慌!莫慌!
最后小伙伴選擇了抽走,是我的工具類不香了么?
當(dāng)然故事的結(jié)果是完美的,問(wèn)題解決了。
事務(wù)
在開(kāi)發(fā)中涉及到同時(shí)操作多個(gè)表的時(shí)候,要保證兩個(gè)操作要么一起成功,要么一起失敗,這時(shí)候就需要用到事務(wù)。
現(xiàn)在一般使用的都是基于 @Transactional 注解的聲明式事務(wù)。
而事務(wù)使用過(guò)程中有以下幾個(gè)注意事項(xiàng):
當(dāng)然這幾句話不是說(shuō)我的,人家官方文檔可是明確說(shuō)明的!
這里可是說(shuō)明了應(yīng)僅將 @Transactional 注解應(yīng)用于具有公開(kāi)可見(jiàn)性的方法。如果對(duì)受 protected, private o或 package-visible 修飾的方法使用,則不會(huì)引發(fā)任何錯(cuò)誤,但是被注解的方法不會(huì)顯示已配置的事務(wù)設(shè)置。
說(shuō)白了,就是你用了,不會(huì)報(bào)錯(cuò),但是不生效!
至于建議加在實(shí)現(xiàn)類上,這個(gè)只是建議,不過(guò)如果加在接口類或接口方法上時(shí),只有配置基于接口的代理才會(huì)生效。所以這塊還是老老實(shí)實(shí)的加在實(shí)現(xiàn)類或?qū)崿F(xiàn)類方法上吧。
因?yàn)榇砟J街粩r截通過(guò)代理傳入的外部方法調(diào)用,所以自調(diào)用事務(wù)是不生效的。
官方的解釋還是比較簡(jiǎn)單明了的,雖然我看不懂,但是不影響我截圖。
那我還是再截一個(gè)吧……
實(shí)際使用
但是在開(kāi)發(fā)中,小伙伴們往往會(huì)遇到這種情況!
本來(lái)自己寫的代碼就一坨坨的又臭又長(zhǎng),里面有各種驗(yàn)簽、驗(yàn)參、查詢、驗(yàn)證等等,就想著來(lái)個(gè)事務(wù),讓事務(wù)包裹的范圍最小,僅僅在同時(shí)更新的時(shí)候加上事務(wù)吧!
這么寫,咦~ IDEA 報(bào)錯(cuò)了,好像不能 private 修飾,那我改成 public。
很顯然事務(wù)是不生效的。
把更新的代碼放到又臭又長(zhǎng)的代碼里面,讓它變得更臭更長(zhǎng),然后用 @Transactional 注解一加。完美解決!
請(qǐng)放過(guò)那坨代碼吧!來(lái)看看下面的辦法。
解決方案 1
那我改成外部調(diào)用不就行了么?
再聲明一個(gè) Service,把更新表的邏輯放過(guò)去。
我一般就喜歡使用這個(gè)辦法。
解決方案 2
使用編程式事務(wù),前面說(shuō)了,使用聲明式事務(wù)時(shí),又這又那,我換一種總可以吧!
你看,我還把方法改成 private 修飾了,事務(wù)也生效。完美解決!
其實(shí)這個(gè)方法也很不錯(cuò)哦!
解決方案 3
又想用注解,又想自調(diào)用怎么辦?
不過(guò)... 麻煩一點(diǎn)還是可以的。
咱們可以參考編程式事務(wù)的方式,不就是不讓自調(diào)用么,我調(diào)外部方法,然后外部方法再給我調(diào)回來(lái)不就可以了。
@Component public class TransactionalComponent {public interface Cell {void run() throws Exception;}@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)public void required(Cell cell) throws Exception {cell.run();} }這樣的話不就可以通過(guò) TransactionalComponent 調(diào)用了么,并且還可以使用 lambda 表達(dá)式。
當(dāng)然基于這個(gè)版本也可以做一個(gè)迭代,就是使用靜態(tài)方法調(diào)用,不用每次都用 @Autowired 注入一次。
public class TransactionalUtils {private static volatile TransactionalComponent transactionalComponent;private static synchronized TransactionalComponent getTransactionalComponent() {if (transactionalComponent == null) {// 從容器中獲取 transactionalComponenttransactionalComponent = ApplicationContextUtils.getBean(TransactionalComponent.class);}return transactionalComponent;}public static void required(TransactionalComponent.Cell cell) throws Exception {getTransactionalComponent().required(cell);}}這樣通過(guò)工具類 TransactionalUtils 便可以直接調(diào)用靜態(tài)方法的方式執(zhí)行事務(wù)操作。
總結(jié)
結(jié)束語(yǔ)
本文主要介紹為什么會(huì)遇到事務(wù)失效,以及事務(wù)失效的避免方式,同時(shí)提供了三種方式來(lái)解決自調(diào)用事務(wù)失效的問(wèn)題。不足之處,歡迎指正。
相關(guān)資料
總結(jié)
以上是生活随笔為你收集整理的wordpress外部调用到html_Spring 自调用事务失效,你是怎么解决的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c++禁止进程被结束_多进程任务实现
- 下一篇: 基片集成波导原理_图解分析:华为1:8