1. 程式人生 > >Never stop for the code

Never stop for the code

本文主要講述學習中瞭解的Spring事務的5種屬性詳情

事務5種屬性
1.事務傳播性 propagation
2.事務隔離性 isolation
3.事務回滾屬性 rollbackfor…等
4.事務只讀屬性 readonly && 事務超時屬性 timeout

用@Transaction宣告註解方式程式碼圖片例項
這裡寫圖片描述

1).事務傳播屬性

  1. 當事務方法被另一個事務方法呼叫時, 必須指定事務應該如何傳播. 例如: 方法可能繼續在現有事務中執行, 也可能開啟一個新事務,
    並在自己的事務中執行.
  2. 事務的傳播行為可以由傳播屬性指定. Spring 定義了 7 種類傳播行為.

這裡寫圖片描述

常用的有REQUIRED 和 REQUIRED_NEW 屬性

按著需求來介紹

  • 新定義 Cashier 介面: 表示客戶的結賬操作
  • 修改資料表資訊如下, 目的是使用者 Tom 在結賬時, 餘額只能支付第一本書, 不夠支付第二本書:

    這裡寫圖片描述

Propagation 屬性設定為REQUIRED 時事務情況

  1. 當 bookService 的 purchase() 方法被另一個事務方法 checkout() 呼叫時, 它預設會在現有的事務內執行.這個預設的傳播行為就是REQUIRED. 因此在 checkout() 方法的開始和終止邊界內只有一個事務. 這個事務只在
    checkout() 方法結束的時候被提交, 結果使用者一本書都買不了
  2. 事務傳播屬性可以在 @Transactional 註解的 propagation 屬性中定義
    如圖所示 事務情況
    這裡寫圖片描述

Propagation 屬性設定為REQUIRED_NEW 時事務情況
另一種常見的傳播行為是 REQUIRES_NEW. 它表示該方法必須啟動一個新事務, 並在自己的事務內執行. 如果有事務在執行, 就應該先掛起它.
如圖所示:
這裡寫圖片描述
傳播性還可以通過xml配置下,如圖
這裡寫圖片描述

那麼併發事務也會導致的一些問題
**當同一個應用程式或者不同應用程式中的多個事務在同一個資料集上併發執行時, 可能會出現許多意外的問題
併發事務所導致的問題可以分為下面三種類型:

  1. 髒讀: 對於兩個事物 T1, T2, T1 讀取了已經被 T2 更新但還沒有被提交的欄位. 之後, 若 T2 回滾,T1讀取的內容就是臨時且無效的.
  2. 不可重複讀:對於兩個事物 T1, T2, T1 讀取了一個欄位, 然後 T2 更新了該欄位. 之後, T1再次讀取同一個欄位,值就不同了.
  3. 幻讀:對於兩個事物 T1, T2, T1 從一個表中讀取了一個欄位, 然後 T2 在該表中插入了一些新的行. 之後, 如果 T1再次讀取同一個表, 就會多出幾行.
    因此我們需要將事務與事務之間隔離。

2).事務隔離性
- 從理論上來說, 事務應該彼此完全隔離, 以避免併發事務所導致的問題. 然而, 那樣會對效能產生極大的影響, 因為事務必須按順序執行.
- 在實際開發中, 為了提升效能, 事務會以較低的隔離級別執行.
- 事務的隔離級別可以通過隔離事務屬性指定

1.事務隔離級別
Sping支援的事務隔離級別:上圖
這裡寫圖片描述

  1. 事務的隔離級別要得到底層資料庫引擎的支援, 而不是應用程式或者框架的支援.
  2. Oracle 支援的 2 種事務隔離級別:READ_COMMITED , SERIALIZABLE
  3. Mysql 支援 4 中事務隔離級別.

3).設定回滾事務

  1. 預設情況下只有未檢查異常(RuntimeException和Error型別的異常)會導致事務回滾. 而受檢查異常不會.
  2. 事務的回滾規則可以通過 @Transactional 註解的 rollbackFor 和 noRollbackFor 屬性來定義.這兩個屬性被宣告為 Class[] 型別的, 因此可以為這兩個屬性指定多個異常類.:上圖
    這裡寫圖片描述
  3. rollbackFor: 遇到IO、SQL Exception 時必須進行回滾
  4. noRollbackFor: 一組異常類,遇到ArithmeticException 時必須不回滾
  5. 一般這個值是不設定的,預設未檢查異常(RuntimeException和Error型別的異常)會回滾。

4).超時和只讀屬性 readonly & timeout

為什麼要有這兩個屬性

  • 由於事務可以在行和表上獲得鎖, 因此長時間的事務會佔用資源, 並對整體效能產生影響. 所以引入超時屬性。
  • 超時事務屬性: 事務在強制回滾之前可以保持多久. 這樣可以防止長期執行的事務佔用資源.
  • 如果一個事物只讀取資料但不做修改, 資料庫引擎可以對這個事務進行優化.所以引入只讀屬性。
  • 只讀事務屬性: 表示這個事務只讀取資料但不更新資料, 這樣可以幫助資料庫引擎優化事務.

設定超時和只讀事務屬性
超時和只讀屬性可以在 @Transactional 註解中定義.超時屬性以秒為單位來計算.上圖:

這裡寫圖片描述

在 Spring 2.x 事務通知中, 超時和只讀屬性可以在 元素中進行指定. 上圖:
這裡寫圖片描述

以上就是Sping事務屬性的詳細總結。