spring事務管理之踩坑一

2021-10-04 14:11:47 字數 2053 閱讀 4725

先來說下該博文的創作背景,要從一道經典的面試(網傳是)說起下面貼上原始碼

@autowired

public void parent()

public void child()

示例中兩個方法要求如何改造使得child() 方法不能影響parent() 方法的執行,換句話說就是正常情況下保證parent() 方法的正常執行,而child() 無關緊要。

然後就各顯神通廢話不多說,出現啦下面這個看似正確完美的版本,直接貼原始碼:

@transactional

public void parent() catch (exception e) "+e);

}user user = new user();

user.setname("lgh").setmobile("18813140000");

}@transactional(propagation = propagation.requires_new)

public void child()

事實證明執行完畢之後,parent 和 child 方法都成功啦,通過日誌發現child 的事務並沒有建立執行,也就是說 child 的事務沒有起作用,因為spring的事務是通過aop實現的,說到底也就是jdk 的動態**來實現的。我們就模擬了一下上面的場景通過動態**來說明這個問題所在,jdk 的動態**是通過介面實現的原始碼如下:

public class testserviceimpl implements testservice 

@override

public void child()

@override

public void test()

}

**呼叫實現:

public class testhandler implements invocationhandler 

@override

public object invoke(object proxy, method method, object args) throws throwable

return method.invoke(target, args);

}public static void main(string args) , handler);

service.parent();}}

通過**呼叫parent 方法,內部呼叫 child 方法,日誌列印如下:

事務處理中*******************

child method invoke start

parent method invoke start

也就是說呼叫parent 方法的時候是**類去呼叫的進而列印啦事務處理的日誌,但是child 方法的呼叫並沒有走**類,通過列印該物件 this 得出結論。再parent 方法被**類呼叫的時候,內部呼叫child 方法的物件是目標源物件,而不是**物件。這樣就明朗很多,之所以child 的事務註解失效是因為 child 的呼叫不是 **的呼叫而是源目標物件本身的呼叫。

如果想實現child 的事務註解生效,顯而易見需要使用**類去呼叫child 方法,實現如下:

@transactional

public void parent() catch (exception e) "+e);

}user user = new user();

user.setname("lgh").setmobile("18813140000");

}@transactional(propagation = propagation.requires_new)

public void child()

說到這呢幫大家再回顧下事務的傳播屬性及隔離級別:請參考

spring事務管理(一)

platformtransactionmanager 事務管理器 transactiondefinition 事務定義資訊 隔離 傳播 超時 唯讀 transactionstatus 事務具體執行狀態 spring為不同的持久化框架提供了不同的platformtransactionmanager.內...

Spring事務管理

spring是ssh中的管理員,負責管理其它框架,協調各個部分的工作。今天一起學習一下spring的事務管理。spring的事務管理分為宣告式跟程式設計式。宣告式就是在spring的配置檔案中進行相關配置 程式設計式就是用註解的方式寫到 裡。下面先說宣告式 spring配置檔案中關於事務配置總是由三...

spring事務管理

一 xml配置事務 二 註解的方式配置事務 bean id txmanaager class org.springframework.orm.hibernate3.hibernatetransactionmanager property name sessionfactory ref session...