0
0
PostgresqlHow-ToBeginner · 3 min read

How to Use SELECT FOR NO KEY UPDATE in PostgreSQL

In PostgreSQL, use SELECT ... FOR NO KEY UPDATE to lock selected rows against concurrent updates that change key columns, but still allow other non-key updates. This lock mode is less restrictive than FOR UPDATE, preventing key conflicts while allowing more concurrency.
📐

Syntax

The basic syntax for SELECT FOR NO KEY UPDATE is:

  • SELECT columns FROM table: Choose the data you want.
  • FOR NO KEY UPDATE: Locks the selected rows to prevent concurrent key updates.

This lock mode blocks other transactions from changing key columns but allows non-key updates and shared locks.

sql
SELECT * FROM table_name WHERE condition FOR NO KEY UPDATE;
💻

Example

This example shows how to lock rows with FOR NO KEY UPDATE to prevent concurrent key updates but allow other updates.

sql
BEGIN;
SELECT * FROM employees WHERE department = 'Sales' FOR NO KEY UPDATE;
-- Do some processing here
COMMIT;
Output
id | name | department ----+-------+------------ 3 | Alice | Sales 7 | Bob | Sales (2 rows)
⚠️

Common Pitfalls

Common mistakes when using FOR NO KEY UPDATE include:

  • Expecting it to block all updates: it only blocks updates to key columns, not all changes.
  • Confusing it with FOR UPDATE, which is more restrictive and blocks all updates.
  • Not using transactions: the lock only holds during the transaction, so forgetting BEGIN and COMMIT makes the lock ineffective.
sql
/* Wrong: no transaction, lock ineffective */
SELECT * FROM employees WHERE department = 'Sales' FOR NO KEY UPDATE;

/* Right: use transaction to hold lock */
BEGIN;
SELECT * FROM employees WHERE department = 'Sales' FOR NO KEY UPDATE;
-- process
COMMIT;
📊

Quick Reference

Lock ModeBlocksAllowsUse Case
FOR NO KEY UPDATEConcurrent key column updatesNon-key updates, shared locksPrevent key conflicts with more concurrency
FOR UPDATEAll concurrent updatesNo concurrent updatesFull row lock for exclusive updates
FOR SHAREExclusive locksOther shared locksRead locks preventing exclusive updates

Key Takeaways

Use FOR NO KEY UPDATE to lock rows against concurrent key changes but allow other updates.
Always run SELECT FOR NO KEY UPDATE inside a transaction to hold the lock.
FOR NO KEY UPDATE is less restrictive than FOR UPDATE, improving concurrency.
It only blocks updates to key columns, not all updates.
Choose the lock mode based on your concurrency and consistency needs.