spring事務隔離級別、傳播行爲

1.事務的定義:事務是指多個操作單元組成的合集,多個單元操作是整體不可分割的,要麼都操作不成功,要麼都成功。其必須遵循四個原則(ACID)。

  1. 原子性(Atomicity):即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全不做;
  2. 一致性(Consistency):在事務執行前數據庫的數據處於正確的狀態,而事務執行完成後數據庫的數據還是應該處於正確的狀態,即數據完整性約束沒有被破壞;如銀行轉帳,A轉帳給B,必須保證A的錢一定轉給B,一定不會出現A的錢轉了但B沒收到,否則數據庫的數據就處於不一致(不正確)的狀態。
  3. 隔離性(Isolation):併發事務執行之間互不影響,在一個事務內部的操作對其他事務是不產生影響,這需要事務隔離級別來指定隔離性;
  4. 持久性(Durability):事務一旦執行成功,它對數據庫的數據的改變必須是永久的,不會因比如遇到系統故障或斷電造成數據不一致或丟失。

2.事務的類型

  1. 數據庫分爲本地事務跟全局事務
    • 本地事務:普通事務,獨立一個數據庫,能保證在該數據庫上操作的ACID。
    • 分佈式事務:涉及兩個或多個數據庫源的事務,即跨越多臺同類或異類數據庫的事務(由每臺數據庫的本地事務組成的),分佈式事務旨在保證這些本地事務的所有操作的ACID,使事務可以跨越多臺數據庫;
  2. Java事務類型分爲JDBC事務跟JTA事務
    • JDBC事務:即爲上面說的數據庫事務中的本地事務,通過connection對象控制管理。
    • JTA事務:JTA指Java事務API(Java Transaction API),是Java EE數據庫事務規範, JTA只提供了事務管理接口,由應用程序服務器廠商(如WebSphere Application Server)提供實現,JTA事務比JDBC更強大,支持分佈式事務
  3. 按是否通過編程分爲聲明式事務和編程式事務,參考http://blog.csdn.net/liaohaojian/article/details/70139151
    • 聲明式事務:通過XML配置或者註解實現。
    • 編程式事務:通過編程代碼在業務邏輯時需要時自行實現,粒度更小。

3.Spring事務隔離級別:spring有五大隔離級別,其在TransactionDefinition接口中定義。看源碼可知,其默isolation_default(底層數據庫默認級別),其他四個隔離級別跟數據庫隔離級別一致。

  1. ISOLATION_DEFAULT:用底層數據庫的默認隔離級別,數據庫管理員設置什麼就是什麼
  2. ISOLATION_READ_UNCOMMITTED(未提交讀):最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀)
  3. ISOLATION_READ_COMMITTED(提交讀):一個事務提交後才能被其他事務讀取到(該隔離級別禁止其他事務讀取到未提交事務的數據、所以還是會造成幻讀、不可重複讀)、sql server默認級別
  4. ISOLATION_REPEATABLE_READ(可重複讀):可重複讀,保證多次讀取同一個數據時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的數據(該隔離基本可防止髒讀,不可重複讀(重點在修改),但會出現幻讀(重點在增加與刪除))(MySql默認級別,更改可通過set transaction isolation level 級別
  5. ISOLATION_SERIALIZABLE(序列化):代價最高最可靠的隔離級別(該隔離級別能防止髒讀、不可重複讀、幻讀)
    1. 丟失更新:兩個事務同時更新一行數據,最後一個事務的更新會覆蓋掉第一個事務的更新,從而導致第一個事務更新的數據丟失,這是由於沒有加鎖造成的;
    2. 幻讀:同樣的事務操作過程中,不同時間段多次(不同事務)讀取同一數據,讀取到的內容不一致(一般是行數變多或變少)。
    3. 髒讀:一個事務讀取到另外一個未提及事務的內容,即爲髒讀。
    4. 不可重複讀:同一事務中,多次讀取內容不一致(一般行數不變,而內容變了)。

幻讀與不可重複讀的區別:幻讀的重點在於插入與刪除,即第二次查詢會發現比第一次查詢數據變少或者變多了,以至於給人一種幻象一樣,而不可重複讀重點在於修改,即第二次查詢會發現查詢結果比第一次查詢結果不一致,即第一次結果已經不可重現了。

數據庫隔離級別越高,執行代價越高,併發執行能力越差,因此在實際項目開發使用時要綜合考慮,爲了考慮併發性能一般使用提交讀隔離級別,它能避免丟失更新和髒讀,儘管不可重複讀和幻讀不能避免,但可以在可能出現的場合使用悲觀鎖或樂觀鎖來解決這些問題。

悲觀鎖與樂觀鎖可參考:http://blog.csdn.net/liaohaojian/article/details/62416972

4.傳播行爲:有七大傳播行爲,也是在TransactionDefinition接口中定義。

  1. PROPAGATION_REQUIRED:支持當前事務,如當前沒有事務,則新建一個。
  2. PROPAGATION_SUPPORTS:支持當前事務,如當前沒有事務,則已非事務性執行(源碼中提示有個注意點,看不太明白,留待後面考究)。
  3. PROPAGATION_MANDATORY:支持當前事務,如當前沒有事務,則拋出異常(強制一定要在一個已經存在的事務中執行,業務方法不可獨自發起自己的事務)。
  4. PROPAGATION_REQUIRES_NEW:始終新建一個事務,如當前原來有事務,則把原事務掛起。
  5. PROPAGATION_NOT_SUPPORTED:不支持當前事務,始終已非事務性方式執行,如當前事務存在,掛起該事務。
  6. PROPAGATION_NEVER:不支持當前事務;如果當前事務存在,則引發異常。
  7. PROPAGATION_NESTED:如果當前事務存在,則在嵌套事務中執行,如果當前沒有事務,則執行與 PROPAGATION_REQUIRED 類似的操作(注意:當應用到JDBC時,只適用JDBC 3.0以上驅動)。

5.Spring事務支持

         不同平臺操作事務的代碼各不相同,spring提供了PlatformTransactionManager 接口

         在spring中事務管理.最爲核心的對象就是TransactionManager對象

spring提供了很多內置事務管理器,支持不同數據源。常見的有三大類
  • DataSourceTransactionManager:org.springframework.jdbc.datasource包下,數據源事務管理類,提供對單個javax.sql.DataSource數據源的事務管理,只要用於JDBC,Mybatis框架事務管理。
  • HibernateTransactionManager:org.springframework.orm.hibernate3包下,數據源事務管理類,提供對單個org.hibernate.SessionFactory事務支持,用於集成Hibernate框架時的事務管理;注意:該事務管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
  • JtaTransactionManager:位於org.springframework.transaction.jta包中,提供對分佈式事務管理的支持,並將事務管理委託給Java EE應用服務器,或者自定義一個本地JTA事務管理器,嵌套到應用程序中。

發佈了0 篇原創文章 · 獲贊 22 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章