話說事務相關知識

前言

自己之前轉載的文章來說Spring中事務的隔離級別和傳播行爲
http://blog.csdn.net/gao36951/article/details/38274275,還有就是關於以mysql爲例的講解數據庫隔離級別的http://blog.csdn.net/gao36951/article/details/38316201但是過一段時間就忘記了,而且還會把數據庫的隔離級別混淆起來。今天就徹底研究了一下,解除這個迷惑。

1.1 事務的四大特性CUID

事務(Transaction)是併發控制的單位,是用戶定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。通過事務,SQL Server能將邏輯相關的一組操作綁定在一起,以便服務器保持數據的完整性。
事務通常是以BEGIN TRANSACTION開始,以COMMIT或ROLLBACK結束。
COMMIT表示提交,即提交事務的所有操作。具體地說就是將事務中所有對數據庫的更新寫回到磁盤上的物理數據庫中去,事務正常結束。
ROLLBACK表示回滾,即在事務運行的過程中發生了某種故障,事務不能繼續進行,系統將事務中對數據庫的所有以完成的操作全部撤消,滾回到事務開始的狀態。

事務的特性(ACID特性)
A:原子性(Atomicity)
事務是數據庫的邏輯工作單位,事務中包括的諸操作要麼全做,要麼全不做。
B:一致性(Consistency)
事務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。一致性與原子性是密切相關的。
C:隔離性(Isolation)
一個事務的執行不能被其他事務干擾。
D:持續性/永久性(Durability)
一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。

1.2 JDBC中的數據隔離級別

如果DBMS支持事務處理,它必須有某種途徑來管理兩個事務同時對一個數據庫進行操作時可能發生的衝突。用戶可指定事務隔離級別,以指明DBMS應該花多大精力來解決潛在衝突。例如,當事務更改了某個值而第二個事務卻在該更改被提交或還原前讀取該值時該怎麼辦。

  假設第一個事務被還原後,第二個事務所讀取的更改值將是無效的,那麼是否可允許這種衝突?JDBC用戶可用以下代碼來指示DBMS允許在值被提交前讀取該值(”dirty讀取”),其中con是當前連接:
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);

   事務隔離級別越高,爲避免衝突所花的精力也就越多。Connection接口定義了五級,其中最低級別指定了根本就不支持事務,而最高級別則指定當事務 在對某個數據庫進行操作時,任何其它事務不得對那個事務正在讀取的數據進行任何更改。通常,隔離級別越高,應用程序執行的速度也就越慢(由於用於鎖定的資 源耗費增加了,而用戶間的併發操作減少了)。在決定採用什麼隔離級別時,開發人員必須在性能需求和數據一致性需求之間進行權衡。當然,實際所能支持的級別 取決於所涉及的DBMS的功能。

  當創建Connection對象時,其事務隔離級別取決於驅動程序,但通常是所涉及的數據庫的缺省 值。用戶可通過調用setIsolationLevel方法來更改事務隔離級別。新的級別將在該連接過程的剩餘時間內生效。要想只改變一個事務的事務隔離 級別,必須在該事務開始前進行設置,並在該事務結束後進行復位。我們不提倡在事務的中途對事務隔離級別進行更改,因爲這將立即觸發commit方法的調 用,使在此之前所作的任何更改變成永久性的。

JDBC的數據隔離級別設置:

JDBC 數據庫隔離級別 數據訪問情況
TRANSACTION_READ_UNCOMMITTED ur 就是俗稱“髒讀”(dirty read),在沒有提交數據時能夠讀到已經更新的數據
TRANSACTION_READ_COMMITTED cs 在一個事務中進行查詢時,允許讀取提交前的數據,數據提交後,當前查詢就可以讀取到數據。update數據時候並不鎖住表
TRANSACTION_REPEATABLE_READ rs 在一個事務中進行查詢時,不允許讀取其他事務update的數據,允許讀取到其他事務提交的新增數據
TRANSACTION_SERIALIZABLE rr 在一個事務中進行查詢時,不允許任何對這個查詢表的數據修改。

1.2.1 JDBC事務隔離級別

    爲了解決與“多個線程請求相同數據”相關的問題,事務之間用鎖相互隔開。多數主流的數據庫支持不同類型的鎖;因此,JDBC API 支持不同類型的事務,它們由 Connection 對象指派或確定。在 JDBC API 中可以獲得下列事務級別:

TRANSACTION_NONE 說明不支持事務。

TRANSACTION_READ_UNCOMMITTED 說明在提交前一個事務可以看到另一個事務的變化。這樣髒讀、不可重複的讀和虛讀都是允許的。

TRANSACTION_READ_COMMITTED 說明讀取未提交的數據是不允許的。這個級別仍然允許不可重複的讀和虛讀產生。

TRANSACTION_REPEATABLE_READ 說明事務保證能夠再次讀取相同的數據而不會失敗,但虛讀仍然會出現。

TRANSACTION_SERIALIZABLE 是最高的事務級別,它防止髒讀、不可重複的讀和虛讀。

    爲了在性能與一致性之間尋求平衡纔出現了上面的幾種級別。事務保護的級別越高,性能損失就越大。 
    假定您的數據庫和 JDBC 驅動程序支持這個特性,則給定一個 Connection 對象,您可以明確地設置想要的事務級別:
    conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ; 
    可以通過下面的方法確定當前事務的級別:
        int level = conn.getTransactionIsolation();
        if(level == Connection.TRANSACTION_NONE)
         System.out.println("TRANSACTION_NONE");
        else if(level == Connection.TRANSACTION_READ_UNCOMMITTED)
         System.out.println("TRANSACTION_READ_UNCOMMITTED");
        else if(level == Connection.TRANSACTION_READ_COMMITTED)
         System.out.println("TRANSACTION_READ_COMMITTED");
        else if(level == Connection.TRANSACTION_REPEATABLE_READ)
         System.out.println("TRANSACTION_REPEATABLE_READ");
        else if(level == Connection.TRANSACTION_SERIALIZABLE)
         System.out.println("TRANSACTION_SERIALIZABLE");

1.3 Spring中的事務隔離級別

使用aop配置事務的時候,除了默認的隔離級別其它四種是和JDBC中的隔離級別相對應的

Isolation[ˌaɪsəˈleɪʃən] 隔離: 屬性一共支持五種事務設置,具體介紹如下:
1、 DEFAULT 使用數據庫設置的隔離級別 ( 默認 ) ,由 DBA 默認的設置來決定隔離級別 .
2、READ_UNCOMMITTED 會出現髒讀、不可重複讀、幻讀 ( 隔離級別最低,併發性能高 )
3、READ_COMMITTED 會出現不可重複讀、幻讀問題(鎖定正在讀取的行)
4、REPEATABLE_READ 會出幻讀(鎖定所讀取的所有行)
5、SERIALIZABLE 保證所有的情況不會發生(鎖表)

1.4 事務的傳播特性propagation

  1. PROPAGATION_REQUIRED: 如果存在一個事務,則支持當前事務。如果沒有事務則開啓
  2. PROPAGATION_SUPPORTS: 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行
  3. PROPAGATION_MANDATORY: 如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。
  4. PROPAGATION_REQUIRES_NEW: 總是開啓一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。
  5. PROPAGATION_NOT_SUPPORTED: 總是非事務地執行,並掛起任何存在的事務。
  6. PROPAGATION_NEVER: 總是非事務地執行,如果存在一個活動事務,則拋出異常
  7. PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行

1.5 主流數據庫默認的隔離級別

  1. Oracle裏支持的隔離級別:read committed/serializable,默認的是read committed
  2. MySQl支持的隔離級別:read uncommitted/read committed/repeatable read/serializable,默認的是repeatable read;

四種併發異常,四種相應的隔離級別參考如下博文
http://blog.csdn.net/bluishglc/article/details/5626009
mysql和oracle中默認隔離級別參考如下博文
http://www.it165.net/database/html/201310/4644.html
Spring事務隔離級別參考如下博文
http://www.cnblogs.com/qqzy168/p/3307284.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章