Lost update xảy ra với luồng đọc — sửa — ghi: hai transaction cùng đọc giá trị cũ, cùng tính toán rồi cùng ghi lại, bản ghi sau đè lên bản ghi trước nên một lần cập nhật biến mất.
-- T1 và T2 chạy đồng thời, cùng đọc stock = 10
SELECT stock FROM products WHERE id = 7; -- cả hai đọc 10
UPDATE products SET stock = 9 WHERE id = 7; -- cả hai ghi 9 → bán 2 nhưng chỉ trừ 1Ba cách chống:
1. Cập nhật nguyên tử trong một câu lệnh — để database tự đọc giá trị mới nhất, không đưa qua application:
UPDATE products SET stock = stock - 1
WHERE id = 7 AND stock > 0; -- kiểm tra rowCount để biết có trừ được không2. Pessimistic lock — SELECT ... FOR UPDATE để giữ hàng trước khi tính toán, transaction thứ hai phải chờ.
3. Optimistic lock — thêm cột version, khi ghi thì kèm điều kiện version cũ; nếu không khớp thì báo xung đột cho tầng trên xử lý.
Cách 1 luôn nên thử trước vì rẻ nhất và không cần giữ khoá lâu. Lưu ý PostgreSQL ở mức REPEATABLE READ trở lên tự phát hiện lost update và ném lỗi serialization, nhưng ở mức mặc định READ COMMITTED thì không — code phải tự lo.