1. 程式人生 > >Spring事務的傳播行為、隔離級別、回滾、只讀和過期

Spring事務的傳播行為、隔離級別、回滾、只讀和過期

事務的傳播性

- 當事務的方法被另一個事務的方法呼叫時,必須指定事務應該如何傳播。如:方法可能繼續在現有的事務中執行,也可能開啟一個新的事務,並在自己的事務中執行。

- 事務的傳播行為可以由傳播屬性指定。Spring定義了7種傳播行為:

required:如果有事務在執行,當前的方法就在這個事務內執行,否則就開啟一個新的事務,並在自己的事務內執行(常用)

required_new:當前的方法必須啟動新事務,並在它自己的事務內執行。如果有事務在執行,應該將其掛起。(常用)

supports:如果有事務在執行,當前這個方法就在這個事務內執行,否則它可以不執行在事務中

not_supported:當前的方法不應該執行在事務中,如果有執行的事務則將其掛起

mandatory:當前的方法必須執行在事務內,如果沒有正在執行的事務,則丟擲異常

never:當前方法不應該執行在事務中,如果有執行的事務,則丟擲異常

nested:如果有事務在執行,當前方法就應該在這個事務的巢狀是事務內執行,否則就啟動一個新的事務,並在自己的事務內執行

required傳播行為:使用呼叫者的事務


requires_new傳播行為:表示該方法必須啟動一個新事務,並在自己的事務內執行,如果有事務在執行就先掛起它。


隔離級別、回滾、只讀和過期

- 當同一個應用程式或不同應用程式中的多個事務在同一個資料集上併發執行的時候,可能會出現意外的問題。

- 併發導致的問題:

1、髒讀:對於兩個事務t1、t2,t1讀取了已經 被t2更新,但還沒有被提交的欄位,之後若t2回滾,t1讀取的內容就是臨時且無效的

2、不可重複讀:對於兩個事務t1、t2,t1讀取了一個欄位,然後t2更新了該欄位,之後t1再讀取同一個欄位,值就不同了

3、幻讀:對於兩個事務t1、t2,t1從一個表中讀取了一個欄位,然後t2在該表中插入了一些新的行,之後,如果t1再次讀取到同一個表就會多出幾行

package dao_tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** * @author chenpeng * @date 2018/6/4 15:29 */ @Service public class BookShopServiceImpl implements BookShopService { @Autowired private BookShopDao bookShopDao; // /** * 1、新增事務註解,使用propagation指定事務的傳播行為,即當前事務方法被另一個事務方法呼叫時,如何使用事務? * 預設取值REQUIRED,即使用呼叫方法的事務 * REQUIRES_NEW:使用自己的事務,呼叫方法的事務被掛起 * 2、isolation:指定事務的隔離級別,預設為READ_COMMITTED * 3、預設情況下Spring的宣告式事務的所有的執行時異常進行回滾,也可以通過對應的屬性進行設定,通常取預設值 * 4、使用readOnly指定事務是否為只讀,表示這個事務只讀取資料但不更新資料,這樣可以幫助資料庫引擎優化事務。 * 如果真的是一個只讀取資料庫值的方法,應設定readOnly=true * 5、使用timeout 指定強制回滾之前事務可以佔用的時間 */ @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED, noRollbackFor = {UserAccountException.class}, readOnly = false,timeout = 1) @Override public void purchase(String username, String isbn) { //1、獲取書的單價 int price = bookShopDao.findBookPriceByIsbn(isbn); //2、更新庫存 bookShopDao.updateBookStock(isbn); //3、更新使用者餘額 bookShopDao.updateUserAccount(username,price); } }