1. 程式人生 > >spring之@Transactional事務傳播性

spring之@Transactional事務傳播性

Required:必須有邏輯事務,否則新建一個事務,使用PROPAGATION_REQUIRED指定,表示如果當前存在一個邏輯事務,則加入該邏輯事務,否則將新建一個邏輯事務,如圖9-2和9-3所示;

 

圖9-2 Required傳播行為

 

圖9-3 Required傳播行為丟擲異常情況

              在前邊示例中就是使用的Required傳播行為:

一、在呼叫userService物件的save方法時,此方法用的是Required傳播行為且此時spring事務管理器發現還沒開啟邏輯事務,因此Spring管理器覺得開啟邏輯事務,

二、在此邏輯事務中呼叫了addressService物件的save方法,而在save方法中發現同樣用的是Required傳播行為,因此使用該已經存在的邏輯事務;

三、在返回到addressService物件的save方法,當事務模板類執行完畢,此時提交併關閉事務。

       因此userService物件的save方法和addressService的save方法屬於同一個物理事務,如果發生回滾,則兩者都回滾。

RequiresNew:建立新的邏輯事務,使用PROPAGATION_REQUIRES_NEW指定,表示每次都建立新的邏輯事務(物理事務也是不同的)如圖9-4和9-5所示:

 

圖9-4 RequiresNew傳播行為

 

圖9-5 RequiresNew傳播行為並丟擲異常

該傳播行為執行流程(正確提交情況):

一、當執行userService物件的save方法時,由於傳播行為是RequiresNew,因此建立一個新的邏輯事務(物理事務也是不同的);

二、當執行到addressService物件的save方法時,由於傳播行為是RequiresNew,因此首先暫停上一個邏輯事務並建立一個新的邏輯事務(物理事務也是不同的);

三、addressService物件的save方法執行完畢後,提交邏輯事務(並提交物理事務)並重新恢復上一個邏輯事務,繼續執行userService物件的save方法內的操作;

四、最後userService物件的save方法執行完畢,提交邏輯事務(並提交物理事務);

五、userService物件的save方法和addressService物件的save方法不屬於同一個邏輯事務且也不屬於同一個物理事務。

Supports

:支援當前事務,使用PROPAGATION_SUPPORTS指定,指如果當前存在邏輯事務,就加入到該邏輯事務,如果當前沒有邏輯事務,就以非事務方式執行,如圖9-6和9-7所示:

 

圖9-6 Required+Supports傳播行為

 

       圖9-7 Supports+Supports傳播行為

NotSupported:不支援事務,如果當前存在事務則暫停該事務,使用PROPAGATION_NOT_SUPPORTED指定,即以非事務方式執行,如果當前存在邏輯事務,就把當前事務暫停,以非事務方式執行,如圖9-8和9-9所示:

 

       圖9-8 Required+NotSupported傳播行為

 

       圖9-9 Supports+NotSupported傳播行為

Mandatory:必須有事務,否則丟擲異常,使用PROPAGATION_MANDATORY指定,使用當前事務執行,如果當前沒有事務,則丟擲異常(IllegalTransactionStateException),如圖9-10和9-11所示:

 

       圖9-10 Required+Mandatory傳播行為

 

       圖9-11 Supports+Mandatory傳播行為

Never:不支援事務,如果當前存在是事務則丟擲異常,使用PROPAGATION_NEVER指定,即以非事務方式執行,如果當前存在事務,則丟擲異常(IllegalTransactionStateException),如圖9-12和9-13所示:

 

       圖9-12 Required+Never傳播行為

 

       圖9-13 Supports+Never傳播行為

Nested:巢狀事務支援,使用PROPAGATION_NESTED指定,如果當前存在事務,則在巢狀事務內執行,如果當前不存在事務,則建立一個新的事務,巢狀事務使用資料庫中的儲存點來實現,即巢狀事務回滾不影響外部事務,但外部事務回滾將導致巢狀事務回滾,如圖9-14和9-15所示:

 

       圖9-14 Required+Nested傳播行為

 

圖9-15 Nested+Nested傳播行為

Nested和RequiresNew的區別:

1、  RequiresNew每次都建立新的獨立的物理事務,而Nested只有一個物理事務;

2、  Nested巢狀事務回滾或提交不會導致外部事務回滾或提交,但外部事務回滾將導致巢狀事務回滾,而 RequiresNew由於都是全新的事務,所以之間是無關聯的;

3、  Nested使用JDBC 3的儲存點實現,即如果使用低版本驅動將導致不支援巢狀事務。

使用巢狀事務,必須確保具體事務管理器實現的nestedTransactionAllowed屬性為true,否則不支援巢狀事務,如DataSourceTransactionManager預設支援,而HibernateTransactionManager預設不支援,需要我們來開啟。