SELECT ... FOR UPDATE 僅在 InnoDB 且事務中生效,鎖粒度取決於 WHERE 條件是否命中主鍵/唯一索引。
| SQL 示例 | 條件特徵 | 鎖類型 | 說明 |
|---|---|---|---|
SELECT * FROM products WHERE id='3' FOR UPDATE; | 明確主鍵,記錄存在 | 行鎖 | 精確鎖定該行 |
SELECT * FROM products WHERE id='-1' FOR UPDATE; | 明確主鍵,記錄不存在 | 無鎖 | 不阻塞其他事務 |
SELECT * FROM products WHERE name='Mouse' FOR UPDATE; | 非索引列/非唯一索引 | 表鎖 | 全表掃描,升級為表鎖 |
SELECT * FROM products WHERE id<>'3' FOR UPDATE; | 範圍/不等於主鍵 | 表鎖 | 無法使用索引定位 |
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE; | 模糊匹配主鍵 | 表鎖 | LIKE 導致索引失效 |
FOR UPDATE 必須在 BEGIN/COMMIT 事務塊中,自動提交模式下鎖即釋放無效。開啟兩個 MySQL 客戶端會話:
會話 1:BEGIN; SELECT * FROM t WHERE id=1 FOR UPDATE; -- 不提交
會話 2:BEGIN; UPDATE t SET v=2 WHERE id=1; -- 觀察是否阻塞