首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 表級鎖實戰:使用 LOCK TABLES 實現唯讀保護

     編輯:MySQL 綜合教學

MySQL 表級鎖實戰:使用 LOCK TABLES 實現唯讀保護

在維護窗口、資料遷移、報表匯出等場景中,常需要暫時禁止表的寫入操作。MySQL 提供 `LOCK TABLES` 機制實現表級別的手動鎖控制。

基本語法

-- 加讀鎖(共享鎖):允許並發讀取,阻塞寫入
LOCK TABLES table_name READ [LOCAL];

-- 加寫鎖(排他鎖):阻塞所有其他讀寫
LOCK TABLES table_name WRITE;

-- 批次鎖定多張表
LOCK TABLES t1 READ, t2 WRITE, t3 READ;

-- 解鎖所有表
UNLOCK TABLES;

實戰範例:設定表為唯讀

mysql> USE test;
Database changed

mysql> LOCK TABLE t_depart_info READ;
Query OK, 0 rows affected (0.00 sec)

-- 嘗試插入資料(會被阻塞/報錯)
mysql> INSERT INTO t_depart_info VALUES (1, 'IT');
ERROR 1099 (HY000): Table 't_depart_info' was locked with a READ lock and can't be updated

-- 其他 Session 查詢正常
mysql> SELECT * FROM t_depart_info;
+----+----------+
| id | name     |
+----+----------+
| 1  | HR       |
+----+----------+

-- 解鎖恢復正常
mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

關鍵特性與限制

特性READ 鎖WRITE 鎖
當前 Session 讀取✅ 允許✅ 允許
當前 Session 寫入❌ 禁止✅ 允許
其他 Session 讀取✅ 允許❌ 阻塞
其他 Session 寫入❌ 阻塞❌ 阻塞
支援 LOCAL 選項✅ (允許並發插入)❌

重要注意事項

  1. 必須一次鎖定所有涉及表:`LOCK TABLES` 是原子操作,無法分步驟加鎖
  2. 不支援鎖升級:持有 READ 鎖無法執行 UPDATE/INSERT/DELETE
  3. 別名也需鎖定:`SELECT a.id FROM emp a` 需 `LOCK TABLES emp AS a READ`
  4. 事務會隱含提交:執行 `LOCK TABLES` 會隱含 `COMMIT` 當前事務
  5. 連線斷開自動釋放:Session 結束自動 `UNLOCK TABLES`

適用場景與替代方案

監控鎖爭用

SHOW GLOBAL STATUS LIKE 'Table_locks%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Table_locks_immediate | 1258  |  -- 立即獲取
| Table_locks_waited    | 0     |  -- 等待次數(>0 表示有爭用)
+-----------------------+-------+

Table_locks_waited 持續增長說明存在嚴重鎖爭用,需檢查長時間持鎖查詢或調整應用邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景建議方案
短時間維護/備份LOCK TABLES READ + mysqldump --single-transaction
長時間唯讀(小時級)REVOKE INSERT/UPDATE/DELETE ON table FROM user
資料遷移同步主庫 READ LOCK → 同步 → 從庫啟動 → UNLOCK
應用層邏輯控制軟刪除/狀態欄位 + 應用攔截器