spring 事務一個被訛傳很廣說法是:一個事務方法不該該調用另外一個事務方法,不然將產生兩個事務。結果形成開發人員在設計事務方法時束手束腳,生怕一不當心就踩到地雷。spring
其實這種是不認識 Spring 事務傳播機制而形成的誤解,Spring 對事務控制的支持統一在 TransactionDefinition 類中描述,該類有如下幾個重要的接口方法:框架
int getPropagationBehavior():事務的傳播行爲spa
int getIsolationLevel():事務的隔離級別.net
int getTimeout():事務的過時時間設計
boolean isReadOnly():事務的讀寫特性。代理
很明顯,除了事務的傳播行爲外,事務的其它特性 Spring 是藉助底層資源的功能來完成的,Spring 無非只充當個代理的角色。可是事務的傳播行爲倒是 Spring 憑藉自身的框架提供的功能,是 Spring 提供給開發者最珍貴的禮物,訛傳的說法玷污了 Spring 事務框架最美麗的光環。orm
所謂事務傳播行爲就是多個事務方法相互調用時,事務如何在這些方法間傳播。Spring 支持 7 種事務傳播行爲:接口
PROPAGATION_REQUIRED 若是當前沒有事務,就新建一個事務,若是已經存在一個事務中,加入到這個事務中。這是最多見的選擇。事務
PROPAGATION_SUPPORTS 支持當前事務,若是當前沒有事務,就以非事務方式執行。資源
PROPAGATION_MANDATORY 使用當前的事務,若是當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW 新建事務,若是當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED 以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER 以非事務方式執行,若是當前存在事務,則拋出異常。
PROPAGATION_NESTED 若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與 PROPAGATION_REQUIRED 相似的操做。
Spring 默認的事務傳播行爲是 PROPAGATION_REQUIRED,它適合於絕大多數的狀況。假設 ServiveX#methodX() 都工做在事務環境下(即都被 Spring 事務加強了),假設程序中存在以下的調用鏈:Service1#method1()->Service2#method2()->Service3#method3(),那麼這 3 個服務類的 3 個方法經過 Spring 的事務傳播機制都工做在同一個事務中。
事務的幾種傳播特性
1. PROPAGATION_REQUIRED: 若是存在一個事務,則支持當前事務。若是沒有事務則開啓 2. PROPAGATION_SUPPORTS: 若是存在一個事務,支持當前事務。若是沒有事務,則非事務的執行 3. PROPAGATION_MANDATORY: 若是已經存在一個事務,支持當前事務。若是沒有一個活動的事務,則拋出異常。 4. PROPAGATION_REQUIRES_NEW: 老是開啓一個新的事務。若是一個事務已經存在,則將這個存在的事務掛起。 5. PROPAGATION_NOT_SUPPORTED: 老是非事務地執行,並掛起任何存在的事務。 6. PROPAGATION_NEVER: 老是非事務地執行,若是存在一個活動事務,則拋出異常 7. PROPAGATION_NESTED:若是一個活動的事務存在,則運行在一個嵌套的事務中. 若是沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行