1. 程式人生 > >spring_(25)Spring_事務其他屬性(隔離級別&回滾&只讀&過期)

spring_(25)Spring_事務其他屬性(隔離級別&回滾&只讀&過期)

併發事務所導致的問題

  • 當同一個應用程式或者不同應用程式中的多個事務在同一個資料集上併發執行時,可能會出現許多意外的問題
  • 併發事務所導致的問題可以分為下面三種類型:
    1. 髒讀:對於兩個事務T1,T2,。T1讀取了已經被T2更新但還沒有被提交的欄位。之後,若T2回滾,T1讀取的內容就是臨時且無效的。
    2. 不可重複讀:對於兩個事務T1,T2, T1讀取了一個欄位,然後T2更新了該欄位。之後,T1再次讀取同一個欄位,值就不同了。
    3. 幻讀:對於兩個事務T1,T2,T1從一個表中讀取了一個欄位,然後T2在該表中插入了一些新的行。之後,如果T1再次讀取同一個表,就會多出幾行。

注意看註釋

package com.spring.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; @Service("bookShopService") 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} )*/ @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED, readOnly = false, timeout = 3) @Override public void purchase(String username, String isbn) { try { Thread.sleep(5000); //時間大於3,所以就算支付成功,也會回滾這個操作 }catch (InterruptedException e){ } //1.獲取書的單價 int price = bookShopDao.findBookPriceByIsbn(isbn); //2.更新書的庫存 bookShopDao.updateBookStock(isbn); //3.更新使用者的餘額 bookShopDao.updateUserAccount(username,price); } }