spring 對事務的控制,是使用 aop 切面實現的,我們不用關心事務的開始,提交 ,回滾,只需要在方法上加 @Transactional
註解,這時候就有問題了。
- 場景一: serviceA 方法調用了 serviceB 方法,但兩個方法都有事務,這個時候如果 serviceB 方法異常,是讓 serviceB 方法提交,還是兩個一起回滾。
- 場景二:serviceA 方法調用了 serviceB 方法,但是隻有 serviceA 方法加了事務,是否把 serviceB 也加入 serviceA 的事務,如果 serviceB 異常,是否回滾 serviceA 。
- 場景三:serviceA 方法調用了 serviceB 方法,兩者都有事務,serviceB 已經正常執行完,但 serviceA 異常,是否需要回滾 serviceB 的數據。
因爲 spring 是使用 aop 來代理事務控制 ,是針對於接口或類的,所以在同一個 service 類中兩個方法的調用,傳播機制是不生效的
傳播機制類型(七種)
一般用得比較多的是
required :合併成一個事務;
requires_new:新建事務,父級異常,它也是正常提交;
nested:成爲父級事務的一個子事務,他異常可以不回滾,父級異常,它必然回滾;
下面的類型都是針對於被調用方法來說的,理解起來要想象成兩個 service 方法的調用纔可以。
PROPAGATION_REQUIRED (默認)required
-
支持當前事務,如果當前沒有事務,則新建事務
-
如果當前存在事務,則加入當前事務,合併成一個事務
REQUIRES_NEW requires_new
-
新建事務,如果當前存在事務,則把當前事務掛起
-
這個方法會獨立提交事務,不受調用者的事務影響,父級異常,它也是正常提交
NESTED
-
如果當前存在事務,它將會成爲父級事務的一個子事務,方法結束後並沒有提交,只有等父事務結束才提交
-
如果當前沒有事務,則新建事務
-
如果它異常,父級可以捕獲它的異常而不進行回滾,正常提交
-
但如果父級異常,它必然回滾,這就是和
REQUIRES_NEW
的區別
SUPPORTS
-
如果當前存在事務,則加入事務
-
如果當前不存在事務,則以非事務方式運行,這個和不寫沒區別
NOT_SUPPORTED
-
以非事務方式運行
-
如果當前存在事務,則把當前事務掛起
MANDATORY
-
如果當前存在事務,則運行在當前事務中
-
如果當前無事務,則拋出異常,也即父級方法必須有事務
NEVER
-
以非事務方式運行,如果當前存在事務,則拋出異常,即父級方法必須無事務