Pessimistic dùng SELECT FOR UPDATE (chặn concurrent writes, risk deadlock); Optimistic dùng version column (retry khi conflict, phù hợp low-contention); SELECT FOR UPDATE SKIP LOCKED là pattern chuẩn cho job queue.
- Pessimistic locking: lock record khi đọc với SELECT FOR UPDATE — ngăn other transactions modify cho đến khi transaction hiện tại commit/rollback.
- An toàn nhưng giảm concurrency, risk deadlock nếu không cẩn thận về lock order.
- Row-level vs table-level: PostgreSQL default là row-level locks (SELECT FOR UPDATE); table-level lock với LOCK TABLE — rất restrictive, tránh dùng.
- SELECT FOR UPDATE SKIP LOCKED: bỏ qua rows đã locked — pattern quan trọng cho job queue, tránh nhiều workers pick cùng job.
- Advisory locks: application-level locks không gắn với specific rows — pg_try_advisory_lock(key) trả về boolean, hữu ích cho distributed coordination (ví dụ chỉ một cron job chạy tại một thời điểm).
- Optimistic locking: không lock, thêm version column (INTEGER) hoặc updated_at timestamp; khi update: UPDATE ...
- WHERE id = ? AND version = ? — nếu 0 rows affected thì concurrent modification đã xảy ra, retry.
- Phù hợp read-heavy, low contention.
- Lock timeout configuration: SET lock_timeout = '5s' tránh query chờ lock vô tận.
- Monitoring locks trong PostgreSQL: SELECT * FROM pg_locks JOIN pg_stat_activity USING (pid) WHERE NOT granted — thấy queries đang chờ lock; pg_blocking_pids(pid) trả về PIDs đang block query.