Required、Required_New傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10259897.html
Nested傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10260066.html
我的Spring事務傳播屬性介紹比較傳送門:https://files.cnblogs.com/files/lvbinbin2yujie/Spring_Tx_Note.rar
事務傳播屬性三. PROPAGATION_MANDATORY
說明: 當前方法必須要在有事務方法中運行,不然就拋出異常;如果有事務,就加入當前事務。
查看運行結果驗證:拋出異常
Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
分析結果:serviceMADATORY方法沒有被事務增強,調用serviceB的testService方法時,發現沒有事務,但是MANDATORY屬性強制要求有事務就會拋出異常;
所以在ServiceA的serviceMANDATORY方法上加上Transactional有事務的注解
查看輸出結果: 可以看到沒有報錯,並且加入了當前全局事務;這種情況就和REQUIRED用法幾乎相同.
事務傳播屬性四:PROPAGATION_NOT_SUPPORTED
說明: 當前方法不應該有事務,如果有事務存在,將它掛起,以無事務狀態運行 (無事務,就是指底層的Connection對象的autoCommit、isolation等屬性與數據庫有關,與dataSource設置的屬性有關,不會被Spring改變,下面會做個試驗測試下.)
修改下ServiceA和ServiceB的測試代碼:
查看輸出日志: NOT_SUPPORTED可以看到將當前事務掛起,在無事務狀態運行,並且在ServiceB方法中做的數據庫操作不會隨着全局事務回退而回退;
實驗一: 修改下ServiceA和ServiceB
ServiceA修改后:
ServiceB修改后:
結合輸出日志: 可以驗證NOT_SUPPORTED確實沒有事務運行
補充:DataSourceUtils的getConnection方法是事務同步的,如果你在ServiceB的方法中執行這樣的方式獲取連接,那ServiceB也會將這個Connection存入TransactionSynchronizationManager的resource線程局部變量上;
事務傳播屬性五. PROPAGATION_NEVER
說明: 當前方法不應該運行在事物中,如果有事務就拋出異常;
ServiceA.java
ServiceB.java (驗證是否有事務)
測試類方法:
查看日志輸出: 同樣獲取了transaction,只不過這種情況下transaction對象都是null,也是沒有事務的意思.
PROPAGATION_NEVER和PROPAGATION_NOT_SUPPORTED區別:
當進入PROPAGATION_NEVER事務的方法時,發現沒有事務就正常運行,發現有事務存在,立刻拋出異常,該方法根本不會執行; 而PROPAGATION_NOT_SUPPORT只是將事務掛起,繼續執行該方法;
NEVER發現事務存在時候拋出的異常情況類似如下:
Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
事務傳播屬性六:PROPAGATION_SUPPORTS
說明: 支持事務,你有事務,ok我加入你的全局事務,成為local transaction;你沒有事務,那我還是可以一樣運行; 這個就不舉例子了.
事務傳播屬性七:PROPAGATION_NESTED
說明: 如果當前有事務在運行,就作為這個事務的內嵌事務運行;當前沒有事務,就新建一個事物運行;
附:NESTED事務見下一篇詳細分析;