事務筆記

什麼是事務

事務是一系列的動做,它們綜合在一塊兒纔是一個完整的工做單元,這些動做必須所有完成,若是有一個失敗的話,那麼事務就會回滾到最開始的狀態,彷彿什麼都沒發生過同樣。 
在企業級應用程序開發中,事務管理必不可少的技術,用來確保數據的完整性和一致性。java

事務四個特性:ACID

  • 原子性(Atomicity):事務是一個原子操做,由一系列動做組成。事務的原子性確保動做要麼所有完成,要麼徹底不起做用。
  • 一致性(Consistency):一旦事務完成(無論成功仍是失敗),系統必須確保它所建模的業務處於一致的狀態,而不會是部分完成部分失敗。在現實中的數據不該該被破壞。
  • 隔離性(Isolation):可能有許多事務會同時處理相同的數據,所以每一個事務都應該與其餘事務隔離開來,防止數據損壞。
  • 持久性(Durability):一旦事務完成,不管發生什麼系統錯誤,它的結果都不該該受到影響,這樣就能從任何系統崩潰中恢復過來。一般狀況下,事務的結果被寫到持久化存儲器中。

spring事務管理器

Spring並不直接管理事務,而是提供了多種事務管理器,他們將事務管理的職責委託給各個框架,spring

因此Spring事務管理的一個優勢就是爲不一樣的事務API提供一致的編程模型,如JTA、JDBC、Hibernate、JPA。數據庫

事務屬性

1.1 傳播行爲

Spring定義了七種傳播行爲:編程

PROPAGATION_REQUIRED 表示當前方法必須運行在事務中。若是當前事務存在,方法將會在該事務中運行。不然,會啓動一個新的事務
PROPAGATION_SUPPORTS 表示當前方法不須要事務上下文,可是若是存在當前事務的話,那麼該方法會在這個事務中運行
PROPAGATION_MANDATORY 表示該方法必須在事務中運行,若是當前事務不存在,則會拋出一個異常
PROPAGATION_REQUIRED_NEW 表示當前方法必須運行在它本身的事務中。一個新的事務將被啓動。若是存在當前事務,在該方法執行期間,當前事務會被掛起。若是使用JTATransactionManager的話,則須要訪問TransactionManager
PROPAGATION_NOT_SUPPORTED 表示該方法不該該運行在事務中。若是存在當前事務,在該方法運行期間,當前事務將被掛起。若是使用JTATransactionManager的話,則須要訪問TransactionManager
PROPAGATION_NEVER 表示當前方法不該該運行在事務上下文中。若是當前正有一個事務在運行,則會拋出異常
PROPAGATION_NESTED 表示若是當前已經存在一個事務,那麼該方法將會在嵌套事務中運行。嵌套的事務能夠獨立於當前事務進行單獨地提交或回滾。若是當前事務不存在,那麼其行爲與PROPAGATION_REQUIRED同樣。注意各廠商對這種傳播行爲的支持是有所差別的。能夠參考資源管理器的文檔來確認它們是否支持嵌套事務

1.2 隔離級別

  • 髒讀(Dirty reads)——髒讀發生在一個事務讀取了另外一個事務改寫但還沒有提交的數據時。若是改寫在稍後被回滾了,那麼第一個事務獲取的數據就是無效的。
  • 不可重複讀(Nonrepeatable read)——不可重複讀發生在一個事務執行相同的查詢兩次或兩次以上,可是每次都獲得不一樣的數據時。這一般是由於另外一個併發事務在兩次查詢期間進行了更新。
  • 幻讀(Phantom read)——幻讀與不可重複讀相似。它發生在一個事務(T1)讀取了幾行數據,接着另外一個併發事務(T2)插入了一些數據時。在隨後的查詢中,第一個事務(T1)就會發現多了一些本來不存在的記錄。

2. 只讀

事務的第三個特性是它是否爲只讀事務。若是事務只對後端的數據庫進行該操做,數據庫能夠利用事務的只讀特性來進行一些特定的優化。經過將事務設置爲只讀,你就能夠給數據庫一個機會,讓它應用它認爲合適的優化措施。後端

 3. 事務超時

爲了使應用程序很好地運行,事務不能運行太長的時間。由於事務可能涉及對後端數據庫的鎖定,因此長時間的事務會沒必要要的佔用數據庫資源。事務超時就是事務的一個定時器,在特定時間內事務若是沒有執行完畢,那麼就會自動回滾,而不是一直等待其結束。併發

 4. 回滾規則

事務五邊形的最後一個方面是一組規則,這些規則定義了哪些異常會致使事務回滾而哪些不會。默認狀況下,事務只有遇到運行期異常時纔會回滾,而在遇到檢查型異常時不會回滾(這一行爲與EJB的回滾行爲是一致的) 
可是你能夠聲明事務在遇到特定的檢查型異常時像遇到運行期異常那樣回滾。一樣,你還能夠聲明事務遇到特定的異常不回滾,即便這些異常是運行期異常。框架

事務狀態

public interface TransactionStatus{
    boolean isNewTransaction(); // 是不是新的事物
    boolean hasSavepoint(); // 是否有恢復點
    void setRollbackOnly();  // 設置爲只回滾
    boolean isRollbackOnly(); // 是否爲只回滾
    boolean isCompleted; // 是否已完成
}
相關文章
相關標籤/搜索