1. 程式人生 > >MySQL(一)MySQL中的隔離級別,事務詳解

MySQL(一)MySQL中的隔離級別,事務詳解

MySQL的基礎語法,增刪改查就不多贅述了,我打算直接從事務開始,以後如果寫到了,再補充相關的知識。

參考文章:

https://www.cnblogs.com/songjy2116/p/7881294.html

https://blog.csdn.net/alexdamiao/article/details/51872477

目錄

一、什麼是事務?

二、事務四大特徵(ACID)

三、事務的原理

 1.undo日誌檔案

 2. redo 日誌檔案

 3.Undo + Redo事務的特點

 4.為了保證Redo Log能夠有比較好的IO效能,InnoDB 的 Redo Log的設計有以下幾個特點:

四、事務的隔離級別

五、不考慮隔離級別可能造成的後果

六、隔離性實現的原理


一、什麼是事務?

  • 事務:一個最小的不可再分的工作單元;通常一個事務對應一個完整的業務(例如銀行賬戶轉賬業務,該業務就是一個最小的工作單元)
  • MySQL 事務主要用於處理操作量大,複雜度高的資料。
  • 在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支援事務。
  • 事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
  • 事務用來管理 insert,update,delete 語句。

示例:銀行轉賬問題

   建立 人員-金額 表如下:

 

  現在丙要給乙轉賬500元,對應的sql如下:

UPDATE money set money = 500 where name = '丙'
UPDATE money set money = 1500 where name = '乙'

  這兩句sql必須要同時執行成功,如果其中一條失敗另外一條也不能成功執行,否則就會出現丙扣了錢但是乙沒有收到錢這種情     況,這個時候就需要用到事務,將這兩句sql放到同一個事務下。

 二、事務四大特徵(ACID)

  • 原子性(A):事務是最小單位,不可再分
  • 一致性(C):事務要求所有的DML語句操作的時候,必須保證同時成功或者同時失敗
  • 隔離性(I):事務A和事務B之間具有隔離性
  • 永續性(D):是事務的保證,事務終結的標誌(記憶體的資料持久到硬碟檔案中)

三、事務的原理

原子性、一致性和永續性是通過redo 和 undo 日誌檔案實現的,不管是redo還是undo檔案都會有一個快取我們稱之為redo_buf和undo_buf。同樣,資料庫檔案也會有快取稱之為data_buf。

   1.undo日誌檔案

undo記錄了資料在事務開始之前的值,當事務執行失敗或者ROLLBACK時可以通過undo記錄的值來恢復資料。例如 AA和BB的初始值分別為3,5。
A 事務開始
B 記錄AA=3到undo_buf
C 修改AA=1
D 記錄BB=5到undo_buf
E 修改BB=7
F 將undo_buf寫到undo(磁碟)
G 將data_buf寫到datafile(磁碟)
H 事務提交
  • 通過undo可以保證原子性、一致性和永續性 
  • 如果事務在F之前崩潰由於資料還沒寫入磁碟,所以資料不會被破壞。 
  • 如果事務在G之前崩潰或者回滾則可以根據undo恢復到初始狀態。 
  • 資料在任務提交之前寫到磁碟保證了永續性。 
  • 這裡有一個隱含的前提條件:‘資料都是先讀到記憶體中,然後修改記憶體中的資料,最後將資料寫回磁碟’。
  • 但是單純使用undo保證原子性和永續性需要在事務提交之前將資料寫到磁碟,浪費大量I/O。

 2. redo 日誌檔案

如果能夠將資料快取一段時間,就能減少IO提高效能。但是這樣就會喪失事務的永續性。因此引入了另外一
種機制來實現持久化,即Redo Log.

A 事務開始
B 記錄AA=3到undo_buf
C 修改AA=1 記錄redo_buf
D 記錄BB=5到undo_buf
E 修改BB=7 記錄redo_buf
F 將redo_buf寫到redo(磁碟)
G 事務提交
  • 通過undo保證事務的原子性,redo保證永續性。 
  • F之前崩潰由於所有資料都在記憶體,恢復後重新衝磁碟載入之前的資料,資料沒有被破壞。 
  • FG之間的崩潰可以使用redo來恢復。 
  • G之前的回滾都可以使用undo來完成。

 3.Undo + Redo事務的特點

  • 為了保證永續性,必須在事務提交前將Redo Log持久化。
  • 資料不需要在事務提交前寫入磁碟,而是快取在記憶體中。
  • Redo Log保證事務的永續性。
  • Undo Log保證事務的原子性。
  • 有一個隱含的特點,資料必須要晚於redo log寫入持久儲存。

Undo + Redo的設計主要考慮的是提升IO效能。雖說通過快取資料,減少了寫資料的IO. 但是卻引入了新的IO,即寫Redo Log的IO。如果Redo Log的IO效能不好,就不能起到提高效能的目的。

 4.為了保證Redo Log能夠有比較好的IO效能,InnoDB 的 Redo Log的設計有以下幾個特點:

  • 儘量保持Redo Log儲存在一段連續的空間上。因此在系統第一次啟動時就會將日誌檔案的空間完全分配。以順序追加的方式記錄Redo Log,通過順序IO來改善效能。
  • 批量寫入日誌。日誌並不是直接寫入檔案,而是先寫入redo log buffer.當需要將日誌重新整理到磁碟時 (如事務提交),將許多日誌一起寫入磁碟.
  • 併發的事務共享Redo Log的儲存空間,它們的Redo Log按語句的執行順序,依次交替的記錄在一起,以減少日誌佔用的空間。例如,Redo Log中的記錄內容可能是這樣的:

        記錄1: <trx1, insert …>

        記錄2: <trx2, update …>

        記錄3: <trx1, delete …>

        記錄4: <trx3, update …>

        記錄5: <trx2, insert …>

  • 因為第三個原因,當一個事務將Redo Log寫入磁碟時,也會將其他未提交的事務的日誌寫入磁碟。
  •  Redo Log上只進行順序追加的操作,當一個事務需要回滾時,它的Redo Log記錄也不會從Redo Log中刪除掉。

事務的隔離級別

事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommitted)
讀已提交(read-committed)
可重複讀(repeatable-read)
序列化(serializable)
mysql預設的事務隔離級別為repeatable-read 

 

五、不考慮隔離級別可能造成的後果

  • 髒讀:事務A讀取了事務B更新的資料,然後B回滾操作,那麼A讀取到的資料是髒資料
  • 不可重複讀:事務 A 多次讀取同一資料,事務 B 在事務A多次讀取的過程中,對資料作了更新並提交,導致事務A多次讀取同一資料時,結果 不一致。
  • 幻讀:系統管理員A將資料庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表

六、隔離性實現的原理

這部分內容涉及到鎖,資料庫引擎,mvcc等內容,在下篇部落格中單獨做一章總結。