當同一個應用程序或者不一樣應用程序的多個事務在同一個數據集上併發操做時,可能會引發以下的問題,簡稱爲併發事務所致使的問題:
1.髒讀:對於兩個事務T1和T2,T1讀取了已經被T2更新但未提交(保存)的自斷後,若T2出現回滾,則T1讀取的內容是臨時無效的。
2.不可重複讀:對於兩個事務T一、T2,T1讀取了一個字段,而後T2更新了該字段,接着T1再次讀取同一字段,值不一樣了。對於T1而言,就出現問題了,一次網絡請求,可是T1兩次讀取同一字段值不同。
3.幻讀:對於兩個事務T一、T2,T1從一個表中讀取了一個字段,T2向該表中插入了一些新的行,以後T1再次讀取同一個表,則會多出幾行。數據庫
//聲明式事務 //1.使用propagation指定事務的傳播行爲 //默認狀況下使用外部整體事務,即便用REQUIRED //REQUIRES_NEW:使用本身的事務,外部事務被掛起 //--------- //2.使用isolation指定事務的隔離級別,經常使用的是READ_COMMITTED //3.使用noRollbackFor/RollbackFor指定事務的回滾,默認狀況下 sring的聲明式事務對全部的運行時異常進行回滾,也能夠經過對應的屬性進行設置 //3.1 忽略UserBalanceException,即noRollbackFor={UserBalanceException.class},該異常不回滾 //4.使用readOnly屬性指定事務是否爲只讀,若是設置成true,表示這個事務只讀取數據不更新數據,這樣 能夠幫助數據庫引擎優化事務。 //5.使用timeOut指定強制回滾以前事務能夠佔用的時間,好處是不讓這個事務佔用過長的時間 @Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, //noRollbackFor={UserBalanceException.class} readOnly =false, timeout = 1) @Override public void purchase(int userId, int bookId) { //1.獲取書的單價 double price = bookShopDao.getBookPriceByBookId(bookId); System.out.println(price); //2.更新書的數量 bookShopDao.updateBookStock(bookId); //3.更新用戶餘額 bookShopDao.updateUserBalance(userId, price); }