Cả ba đều là row-level lock lấy tường minh trong một SELECT, khác nhau ở mức độ chặt và ở việc chặn ai.
FOR UPDATE— chặt nhất. Giữ hàng để chính bạn sửa hoặc xoá; mọi transaction khác muốnFOR UPDATE,FOR SHARE,UPDATEhayDELETEtrên hàng đó đều phải chờ.FOR NO KEY UPDATE— nhẹ hơn, cho phép sửa các cột không thuộc key. Đây chính là mức khoá mà một câuUPDATEthường tự lấy. Nó không chặnFOR KEY SHARE, nên transaction khác vẫn chèn được hàng con tham chiếu tới nó.FOR SHARE— khoá chia sẻ: nhiều transaction cùng đọc và cùng giữ được, nhưng tất cả đều chặn người muốn sửa. Dùng khi bạn cần đảm bảo hàng đó không đổi đến cuối transaction mà bản thân không sửa nó.
sql
BEGIN;
SELECT balance FROM wallets WHERE user_id = 42 FOR UPDATE; -- giữ hàng
UPDATE wallets SET balance = balance - 100 WHERE user_id = 42;
COMMIT; -- khoá nhả ở đâyLưu ý: khoá chỉ nhả khi transaction kết thúc, nên đừng đặt lệnh gọi mạng vào giữa SELECT FOR UPDATE và COMMIT.
Khi cần khoá quan hệ cha–con, chọn FOR NO KEY UPDATE cho hàng cha để không chặn oan việc chèn hàng con.