前言
自己之前轉載的文章來說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 PROPAGATION_REQUIRED: 如果存在一個事務,則支援當前事務。如果沒有事務則開啟 PROPAGATION_SUPPORTS: 如果存在一個事務,支援當前事務。如果沒有事務,則非事務的執行 PROPAGATION_MANDATORY: 如果已經存在一個事務,支援當前事務。如果沒有一個活動的事務,則拋出異常。 PROPAGATION_REQUIRES_NEW: 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。 PROPAGATION_NOT_SUPPORTED: 總是非事務地執行,並掛起任何存在的事務。 PROPAGATION_NEVER: 總是非事務地執行,如果存在一個活動事務,則拋出異常 PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行 1.5 主流資料庫預設的隔離等級 Oracle裡支援的隔離等級:read committed/serializable,預設的是read committed 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