日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

事务(ACID)、并发一致性问题(丢失修改、读脏数据、不可重复读、幻影读)、封锁(封锁粒度、类型、协议、MySQL 隐式与显示锁定)

發布時間:2024/10/14 80 豆豆

1. 事務

1.1 概念

事務指的是滿足 ACID 特性的一組操作,可以通過 Commit 提交一個事務,也可以使用 Rollback 進行回滾。

1.2?ACID

1.2.1? 原子性(Atomicity)

事務被視為不可分割的最小單元,事務的所有操作要么全部提交成功,要么全部失敗回滾。

回滾可以用日志來實現,日志記錄著事務所執行的修改操作,在回滾時反向執行這些修改操作即可。

1.2.2 一致性(Consistency)

數據庫在事務執行前后都保持一致性狀態。在一致性狀態下,所有事務對一個數據的讀取結果都是相同的。

1.2.3? 隔離性(Isolation)

一個事務所做的修改在最終提交以前,對其它事務是不可見的。

1.2.4 持久性(Durability)

一旦事務提交,則其所做的修改將會永遠保存到數據庫中。即使系統發生崩潰,事務執行的結果也不能丟失。

可以通過數據庫備份和恢復來實現,在系統發生崩潰時,使用備份的數據庫進行數據恢復。

事務的 ACID 特性概念簡單,但不是很好理解,主要是因為這幾個特性不是一種平級關系:

  • 只有滿足一致性,事務的執行結果才是正確的。
  • 在無并發的情況下,事務串行執行,隔離性一定能夠滿足。此時只要能滿足原子性,就一定能滿足一致性。
  • 在并發的情況下,多個事務并行執行,事務不僅要滿足原子性,還需要滿足隔離性,才能滿足一致性。
  • 事務滿足持久化是為了能應對數據庫崩潰的情況。

1.3?AUTOCOMMIT

MySQL 默認采用自動提交模式。也就是說,如果不顯式使用 START TRANSACTION 語句來開始一個事務,那么每個查詢都會被當做一個事務自動提交。

2. 并發一致性問題

在并發環境下,事務的隔離性很難保證,因此會出現很多并發一致性問題。

2.1 丟失修改

T1 和 T2 兩個事務都對一個數據進行修改,T1 先修改,T 2隨后修改,T 2的修改覆蓋了T1的修改。

2.2?讀臟數據

T1修改一個數據,T2隨后讀取這個數據。如果 T1撤銷了這次修改,那么 T2讀取的數據是臟數據。

2.3?不可重復讀

T2讀取一個數據,T1對該數據做了修改。如果 T2再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

2.4 幻影讀

T1讀取某個范圍的數據,T2在這個范圍內插入新的數據,T1再次讀取這個范圍的數據,此時讀取的結果和和第一次讀取的結果不同。

產生并發不一致性問題主要原因是破壞了事務的隔離性,解決方法是通過并發控制來保證隔離性。

并發控制可以通過封鎖來實現,但是封鎖操作需要用戶自己控制,相當復雜。

數據庫管理系統提供了事務的隔離級別,讓用戶以一種更輕松的方式處理并發一致性問題。

3. 封鎖

3.1 封鎖粒度

MySQL 中提供了兩種封鎖粒度:行級鎖以及表級鎖。

  • 應該盡量只鎖定需要修改的那部分數據,而不是所有的資源。
  • 鎖定的數據量越少,發生鎖爭用的可能就越小,系統的并發程度就越高。
  • 但是加鎖需要消耗資源,鎖的各種操作(包括獲取鎖、釋放鎖、以及檢查鎖狀態)都會增加系統開銷。
  • 因此封鎖粒度越小,系統開銷就越大。

在選擇封鎖粒度時,需要在鎖開銷和并發程度之間做一個權衡。

3.2?封鎖類型

3.2.1 讀寫鎖

  • 排它鎖(Exclusive) ,簡寫為 X 鎖,又稱寫鎖。
  • 共享鎖(Shared) ,簡寫為 S 鎖,又稱讀鎖。

有以下兩個規定:

一個事務對數據對象 A 加了 X 鎖,就可以對 A 進行讀取和更新。加鎖期間其它事務不能對 A 加任何鎖。

一個事務對數據對象 A 加了 S 鎖,可以對 A 進行讀取操作,但是不能進行更新操作。加鎖期間其它事務能對 A 加 S 鎖,但是不能加 X 鎖。

鎖的兼容關系如下:

-XSXS
××
×

3.2.2 意向鎖

使用意向鎖(Intention Locks) 可以更容易地支持多粒度封鎖。

在存在行級鎖和表級鎖的情況下,事務 T 想要對表 A 加 X 鎖,就需要先檢測是否有其它事務對表 A 或者表 A 中的任意一行加了鎖,那么就需要對表 A 的每一行都檢測一次,這是非常耗時的。

意向鎖在原來的 X/S 鎖之上引入了 IX/IS,IX/IS 都是表鎖,用來表示一個事務想要在表中的某個數據行上加 X 鎖或 S 鎖。

有以下兩個規定:

一個事務在獲得某個數據行對象的 S 鎖之前,必須先獲得表的 IS 鎖或者更強的鎖;

一個事務在獲得某個數據行對象的 X 鎖之前,必須先獲得表的 IX 鎖。

通過引入意向鎖,事務 T 想要對表 A 加 X 鎖,只需要先檢測是否有其它事務對表A 加了 X/IX/S/IS 鎖,如果加了就表示有其它事務正在使用這個表或者表中某一行的鎖,因此事務 T 加 X 鎖失敗。

各種鎖的兼容關系如下:

-XIXSISXIXSIS
××××
××
××
×

解釋如下:

任意 IS/IX 鎖之間都是兼容的,因為它們只是表示想要對表加鎖,而不是真正加鎖;

S 鎖只與 S 鎖和 IS 鎖兼容,也就是說事務 T 想要對數據行加 S 鎖,其它事務可以已經獲得對表或者表中的行的 S 鎖。

3.3 封鎖協議

3.3.1 三級封鎖協議

一級封鎖協議

事務 T 要修改數據 A 時必須加 X 鎖,直到 T 結束才釋放鎖。

可以解決丟失修改問題,因為不能同時有兩個事務對同一個數據進行修改,那么事務的修改就不會被覆蓋。

二級封鎖協議

在一級的基礎上,要求讀取數據 A 時必須加 S 鎖,讀取完馬上釋放 S 鎖。

可以解決讀臟數據問題,因為如果一個事務在對數據 A 進行修改,根據 1 級封鎖協議,會加 X 鎖,那么就不能再加 S 鎖了,也就是不會讀入數據。

三級封鎖協議

在二級的基礎上,要求讀取數據 A 時必須加 S 鎖,直到事務結束了才能釋放 S鎖。

可以解決不可重復讀的問題,因為讀 A 時,其它事務不能對 A 加 X 鎖,從而避免了在讀的期間數據發生改變。

3.3.2 兩段鎖協議

加鎖和解鎖分為兩個階段進行。

可串行化調度是指,通過并發控制,使得并發執行的事務結果與某個串行執行的事務結果相同。

事務遵循兩段鎖協議是保證可串行化調度的充分條件。

例如以下操作滿足兩段鎖協議,它是可串行化調度。

lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B)

但不是必要條件,例如以下操作不滿足兩段鎖協議,但是它還是可串行化調度

lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(C)...unlock(C)

3.4?MySQL 隱式與顯示鎖定

MySQL 的 InnoDB 存儲引擎采用兩段鎖協議,會根據隔離級別在需要的時候自動加鎖,并且所有的鎖都是在同一時刻被釋放,這被稱為隱式鎖定。

InnoDB 也可以使用特定的語句進行顯示鎖定:

SELECT ... LOCK In SHARE MODE; SELECT ... FOR UPDATE;

?

總結

以上是生活随笔為你收集整理的事务(ACID)、并发一致性问题(丢失修改、读脏数据、不可重复读、幻影读)、封锁(封锁粒度、类型、协议、MySQL 隐式与显示锁定)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。