按粒度分類
全局鎖
- 含義:全局鎖會鎖定整個數據庫實例,在其生效期間,其他事務無法對數據庫進行任何讀寫操作。常用于數據遷移、數據備份場景。
表級鎖
- 表鎖:是對整張表進行鎖定的機制。實現邏輯簡單,加鎖和釋放鎖速度快,系統負面影響小,能有效避免死鎖問題。不過,因其鎖定粒度大,鎖定資源爭用概率高,會降低并發度。MyISAM、MEMORY、CSV 等非事務性存儲引擎主要使用表級鎖定。
- 意向鎖:屬于表級鎖,目的是實現多粒度鎖機制,允許行鎖和表鎖共存。分為意向共享鎖(IS)和意向排他鎖(IX) 。意向共享鎖表明事務后續想獲取表中某些行的共享鎖;意向排他鎖則表示事務后續想獲取表中某些行的排他鎖。意向鎖可快速判斷表中是否已有記錄被加鎖,提升加鎖效率。
- 元數據鎖:在執行 DML(增刪改查)或 DDL(結構變更)操作時,數據庫會自動添加。用于保護數據庫對象(如表、視圖等)的元數據信息,防止在操作過程中,元數據被其他事務修改,保證數據結構的一致性和穩定性。
行級鎖
- 記錄鎖:鎖定單個數據記錄。InnoDB 存儲引擎中,若表建立時未設置索引,會使用隱式主鍵進行鎖定。
- 間隙鎖:鎖定索引記錄之間的 “間隙”,防止其他事務在該間隙插入數據。
- 臨鍵鎖:是記錄鎖和間隙鎖的組合,既鎖定當前行,又鎖定該行之后的間隙。
- 插入意向鎖:事務在插入數據時會獲取,用于表示插入意向。它與其他事務的插入意向鎖兼容,不同事務可并發插入數據到同一索引區間,提高插入操作的并發性能。
按行為分類
共享鎖
SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;
- 含義:也叫讀鎖,允許事務讀取數據,但不允許修改。多個事務可同時獲取共享鎖。
- 應用場景:適用于多個事務同時讀取同一數據的場景,如報表生成、數據統計等操作,多個事務可同時加共享鎖讀取數據,互不干擾。
排他鎖
SELECT * FROM table_name WHERE id = 1 FOR UPDATE;
- 含義:又稱寫鎖,只允許一個事務對特定數據進行讀寫操作,其他事務無法對該數據加任何類型的鎖。
- 應用場景:用于數據修改操作,如插入、更新、刪除等。在進行這些操作前,需先加排他鎖,防止其他事務同時修改數據,保證數據修改的原子性和一致性。
按模式分類
悲觀鎖
- 策略:一種假設并發沖突總會發生的策略,每次在訪問數據前,都會對數據加鎖,包括共享鎖、排他鎖等。
- 應用場景:在并發沖突概率較高,或對數據一致性要求極高的場景中適用。例如在金融交易系統中,資金轉賬操作需確保數據準確一致,常使用悲觀鎖防止并發問題。
樂觀鎖
- 策略:假設并發沖突不會發生,不主動加鎖。通常通過版本號或時間戳字段實現。在更新數據時,先比較版本號或時間戳,若數據未被其他事務修改,才進行更新操作。
- 應用場景:適用于并發沖突概率較低的場景,能減少鎖的開銷,提高系統并發性能。如一些讀操作頻繁,寫操作相對較少且沖突概率低的系統中可使用。
避免死鎖
- 確保事務訪問數據順序一致:在多個事務并發訪問數據時,通過合理加鎖,確保事務按特定順序訪問數據,避免因并發操作導致數據不一致。
- 合理使用索引:建立合適索引,能讓查詢更精準,減少鎖的范圍,避免因索引不當導致鎖升級為表鎖,進而降低死鎖風險
- 控制事務大小:使用較小事務,減少事務執行時間和鎖持有時間,降低多個事務互相等待鎖的可能性,從而避免死鎖。
. 控制事務大小:使用較小事務,減少事務執行時間和鎖持有時間,降低多個事務互相等待鎖的可能性,從而避免死鎖。 - 設置鎖等待超時時間:通過設置合理的鎖等待超時時間,當事務等待鎖時間超過該值時自動回滾,打破死鎖循環,防止因死鎖導致系統長時間無法運行。在 MySQL 中,可通過相關參數配置來設置鎖等待超時時間。