因爲自己老是遺忘了spring的事務傳播屬性。究竟是在什麼時候加事務呢?是不是本身service中的方法有事務的情況下去做這個傳播呢?其實,自己老是混淆是不是有事務然後去傳播。。
事實上,所有的service方法都是沒有事務的,當spring做AOP時才加進去的。。當兩個service操作的時候,就會進行事務處理的問題了。這兩個service究竟以什麼方式進行協作呢?是,兩個Service運行時合併事務做,還是嵌套事務。。。就需要用到事務傳播。。以前的誤區就是,如果一個Ation 或者一個別的方法,調用兩個service,應該如何處理。如
public String execute{
serviceA.methodA();
serviceB.methodB();
}
其實這裏沒有什麼所謂的事務傳播,只是分別調用兩個不同的事務方法。如果A回滾了,B也一樣繼續執行的。
實質上它的事務處理是:
execute(){
事務1開始:
methodA();
事務1結束();
事務2開始:
methodB();
事務2結束;
}
而當在service中 如 ServiceC.methodC(){
serviceA.methodA();
serviceB.methodB();
}
因爲serviceC 中的mehodC中本身就AOP了事務,如果C也是PROPAGATION_REQUIRED的話,那麼就要在C中起一個事務。
而methodA()和methodB()中spring就不會重新注入事務了。
即整個流程變成了 C{
事務開始:
methodA();
methodB();
事務提交;
}
關於Spring的事務傳播屬性:
PROPAGATION_REQUIRED -- 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
PROPAGATION_SUPPORTS -- 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY -- 支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED -- 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER -- 以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED -- 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。
前六個策略類似於EJB CMT,第七個(PROPAGATION_NESTED)是Spring所提供的一個特殊變量。
它要求事務管理器或者使用JDBC 3.0 Savepoint API提供嵌套事務行爲(如Spring的DataSourceTransactionManager)
所謂事務傳播屬性,就是有N個Service互相調用的時候,的處理方式。
如 ServiceA有methodA方法,它的事務傳播屬性是:PROPAGATION_REQUIRED 。ServiceB有methodB方法 。它的事務傳播屬性也是:PROPAGATION_REQUIRED
(1)當methodA()中調用serviceB.methodB()時,public methodA(){serviceB.methodB();} 當methodA執行時,根據傳播屬性:PROPAGATION_REQUIRED:如果當前沒有事務,就新建一個事務。
(2)當前methodA()沒有事務。所以spring給它新建了一個事務。
(3)到serviceB.methodB();方法時,因爲methodA()àServiceB.methodB()是一個線程中執行的。當前methodA()已經開啓事務。MethodB()的傳播屬性也是:PROPAGATION_REQUIRED。因爲它是支持當前事務的。所以它繼續用methodA的事務。