程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL中事務概念的簡潔學習教程,mysql事務概念教程

MySQL中事務概念的簡潔學習教程,mysql事務概念教程

編輯:MySQL綜合教程

MySQL中事務概念的簡潔學習教程,mysql事務概念教程


事務是由一步或幾步數據庫操作序列組成邏輯執行單元,這系列操作要麼全部執行,要麼全部放棄執行。程序和事務是兩個不同的概念。一般而言:一段程序中可能包含多個事務。

事務具有四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持續性(Durability)。這四個特性也簡稱ACID性。

1)原子性:事務是應用中最小的執行單位,就如原子是自然界最小顆粒,具有不可再分的特征一樣。事務是應用中不可再分的最小邏輯執行體。

2)一致性:事務執行的結果,必須使數據庫從一個一致性狀態,變到另一個一致性狀態。當數據庫中只包含事務成功提交的結果時,數據庫處於一致性狀態。一致性是通過原子性來保證的。

3)隔離性:各個事務的執行互不干擾,任意一個事務的內部操作對其他並發的事務,都是隔離的。也就是說:並發執行的事務之間不能看到對方的中間狀態,並發執行的事務之間不能相互影響。

4)持續性:持續性也稱為持久性,指事務一旦提交,對數據所做的任何改變,都要記錄到永久存儲器中,通常是保存進物理數據庫。

在關系型數據庫中,事務的隔離性分為四個隔離級別,在解讀這四個級別前先介紹幾個關於讀數據的概念。

1)髒讀(Dirty Reads):所謂髒讀就是對髒數據(Drity Data)的讀取,而髒數據所指的就是未提交的數據。也就是說,一個事務正在對一條記錄做修改,在這個事務完成並提交之前,這條數據是處於待定狀態的(可能提交也可能回滾),這時,第二個事務來讀取這條沒有提交的數據,並據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被稱為髒讀。

2)不可重復讀(Non-Repeatable Reads):一個事務先後讀取同一條記錄,但兩次讀取的數據不同,我們稱之為不可重復讀。也就是說,這個事務在兩次讀取之間該數據被其它事務所修改。

3)幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為幻讀。

 

事務四個隔離級別對比:

1)未提交讀(Read Uncommitted):SELECT語句以非鎖定方式被執行,所以有可能讀到髒數據,隔離級別最低。

2)提交讀(Read Committed):只能讀取到已經提交的數據。即解決了髒讀,但未解決不可重復讀。

3)可重復讀(Repeated Read):在同一個事務內的查詢都是事務開始時刻一致的,InnoDB的默認級別。在SQL標准中,該隔離級別消除了不可重復讀,但是還存在幻讀。

4)串行讀(Serializable):完全的串行化讀,所有SELECT語句都被隱式的轉換成SELECT ... LOCK IN SHARE MODE,即讀取使用表級共享鎖,讀寫相互都會阻塞。隔離級別最高。


隔離級別對比表:

20151118175418212.jpg (589×166)

數據庫的事務有下列語句組成:

一組DML(Data Manipulate Language,即數據操作語言)經過這組DML修改後數據將保持較好的一致性。

一個DDL(Data Definition Language,即數據定義語言)語句。

一個DCL(Data control Language,即數據控制語言)語句。

       DDL和DCL語句最多只能有一個,因為DDL和DCL語句都會導致事務立即提交。

       當事務所包含的全部數據庫操作都成功執行後,應該提交(commit)事務,使這些修改永久生效。

       事務提交有兩種方式:顯式提交和自動提交。

(1)顯式提交:使用commit。

(2)自動提交:執行DDL或DCL,或者程序正常退出。

數據庫事務傳播級別,指的是事務嵌套時,應該采用什麼策略,即在一個事務中調用別的事務,該怎麼辦

假如有一下兩個事務:

ServiceA {  
     void methodA ()  {  
     ServiceB . methodB ();  
   }  
  
}  
  
ServiceB {  
   void methodB ()  {  
   }   
} 

1 : PROPAGATION_REQUIRED

加入當前正要執行的事務不在另外一個事務裡,那麼就起一個新的事務

比如說, ServiceB.methodB 的事務級別定義為 PROPAGATION_REQUIRED, 那麼由於執行 ServiceA.methodA 的時候,

ServiceA.methodA 已經起了事務,這時調用 ServiceB.methodB , ServiceB.methodB 看到自己已經運行在 ServiceA.methodA

的事務內部,就不再起新的事務。而假如 ServiceA.methodA 運行的時候發現自己沒有在事務中,他就會為自己分配一個事務。

這樣,在 ServiceA.methodA 或者在 ServiceB.methodB 內的任何地方出現異常,事務都會被回滾。即使 ServiceB.methodB 的事務已經被

提交,但是 ServiceA.methodA 在接下來 fail 要回滾, ServiceB.methodB 也要回滾

2 : PROPAGATION_SUPPORTS

如果當前在事務中,即以事務的形式運行,如果當前不再一個事務中,那麼就以非事務的形式運行

3 : PROPAGATION_MANDATORY

必須在一個事務中運行。也就是說,他只能被一個父事務調用。否則,他就要拋出異常

4 : PROPAGATION_REQUIRES_NEW

這個就比較繞口了。 比如我們設計 ServiceA.methodA 的事務級別為 PROPAGATION_REQUIRED , ServiceB.methodB 的事務級別為 PROPAGATION_REQUIRES_NEW ,

那麼當執行到 ServiceB.methodB 的時候, ServiceA.methodA 所在的事務就會掛起, ServiceB.methodB 會起一個新的事務,等待 ServiceB.methodB 的事務完成以後,

他才繼續執行。他與 PROPAGATION_REQUIRED 的事務區別在於事務的回滾程度了。因為 ServiceB.methodB 是新起一個事務,那麼就是存在

兩個不同的事務。如果 ServiceB.methodB 已經提交,那麼 ServiceA.methodA 失敗回滾, ServiceB.methodB 是不會回滾的。如果 ServiceB.methodB 失敗回滾,

如果他拋出的異常被 ServiceA.methodA 捕獲, ServiceA.methodA 事務仍然可能提交。

5 : PROPAGATION_NOT_SUPPORTED

當前不支持事務。比如 ServiceA.methodA 的事務級別是 PROPAGATION_REQUIRED ,而 ServiceB.methodB 的事務級別是 PROPAGATION_NOT_SUPPORTED ,

那麼當執行到 ServiceB.methodB 時, ServiceA.methodA 的事務掛起,而他以非事務的狀態運行完,再繼續 ServiceA.methodA 的事務。

6 : PROPAGATION_NEVER

不能在事務中運行。假設 ServiceA.methodA 的事務級別是 PROPAGATION_REQUIRED , 而 ServiceB.methodB 的事務級別是 PROPAGATION_NEVER ,

那麼 ServiceB.methodB 就要拋出異常了。

7 : PROPAGATION_NESTED

理解 Nested 的關鍵是 savepoint 。他與 PROPAGATION_REQUIRES_NEW 的區別是, PROPAGATION_REQUIRES_NEW 另起一個事務,將會與他的父事務相互獨立,

而 Nested 的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最後回滾,他也要回滾的。

而 Nested 事務的好處是他有一個 savepoint 。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved