MYSQL的事務詳解

本兮言發表於2018-12-22

資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 

四大特徵:

(1)原子性

事務必須是原子工作單元;對於其資料修改,要麼全都執行,要麼全都不執行。

(2)一致性

事務的一致性指的是在一個事務執行之前和執行之後資料庫都必須處於一致性狀態。事務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。

(3) 隔離性(關於事務的隔離性資料庫提供了多種隔離級別)

一個事務的執行不能干擾其它事務。即一個事務內部的操作及使用的資料對其它併發事務是隔離的,併發執行的各個事務之間不能互相干擾。

(4)永續性

事務完成之後,它對於資料庫中的資料改變是永久性的。該修改即使出現系統故障也將一

直保持。

在介紹資料庫提供的各種隔離級別之前,我們先看看如果不考慮事務的隔離性,會發生的幾種問題:

l 髒讀

髒讀是指在一個事務處理過程裡讀取了另一個未提交的事務中的資料。

l 不可重複讀

l 幻讀

幻讀和不可重複讀都是讀取了另一條已經提交的事務,不可重複讀重點在於update和delete,而幻讀的重點在於insert。

在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖,其它事務無法修改這些資料,就可以實現可重複 讀了。但這種方法卻無法鎖住insert的資料,所以當事務A先前讀取了資料,或者修改了全部資料,事務B還是可以insert資料提交,這時事務A就會 發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低資料庫的併發能力。

 

現在來看看MySQL資料庫為我們提供的四種隔離級別:

  ① Serializable (序列化):可避免髒讀、不可重複讀、幻讀的發生。

  ② Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。

  ③ Read committed (讀已提交):可避免髒讀的發生。

④ Read uncommitted (讀未提交):最低階別,任何情況都無法保證。

 

在MySQL資料庫中預設的隔離級別為Repeatable read (可重複讀)。

 

 

鎖模式包括: 

l 共享鎖:(讀取)操作建立的鎖。其他使用者可以併發讀取資料,但任何事物都不能獲取資料上的排它鎖,直到已釋放所有共享鎖。

l 排他鎖(X鎖):對資料A加上排他鎖後,則其他事務不能再對A加任任何型別的封鎖。獲准排他鎖的事務既能讀資料,又能修改資料。

l 更新鎖:
更新 (U) 鎖可以防止通常形式的死鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新資料,則兩個事務需都要轉換共享鎖為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。
若要避免這種潛 在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共享鎖。

 

鎖的粒度主要有以下幾種型別:

l 行鎖: 粒度最小,併發性最高

l 頁鎖:一次鎖定一頁。25個行鎖可升級為一個頁鎖。

l 表鎖:粒度大,併發性低

l 資料庫鎖:控制整個資料庫操作

 

樂觀鎖:相對悲觀鎖而言,樂觀鎖假設認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做。一般的實現樂觀鎖的方式就是記錄資料版本。

悲觀鎖:顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

相關文章