FOR is a reserved keyword that augments a SELECT query with additional behavior. In transactional databases it most often appears as FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE, or FOR KEY SHARE to lock the selected rows until the current transaction ends. This prevents concurrent sessions from modifying (or, with SHARE clauses, modifying or locking) the same rows and eliminates lost-update anomalies.Some dialects also use FOR to switch the result format (FOR JSON, FOR XML), to stream results forward-only (FORWARD_ONLY in SQL Server), or to set read-only intent (FOR READ ONLY in Oracle). The common denominator is that the keyword FOR signals that what follows changes how the result set is treated by the optimizer, the lock manager, or the client API.Key behaviors- Executes immediately after the FROM clause and optional WHERE/GROUP/ORDER clauses.- Applies locks at the row level, not the table level, unless the optimizer cannot find a suitable index.- Honors the transaction isolation level but can still block or be blocked by concurrent statements.- Optional modifiers NOWAIT and SKIP LOCKED control blocking behavior.Caveats- FOR UPDATE rows cannot be updated by other sessions until COMMIT or ROLLBACK.- In PostgreSQL, combining FOR UPDATE with LIMIT requires an ORDER BY to avoid unpredictable locking order.- SQLite ignores FOR UPDATE; using it has no effect.- Misuse may cause deadlocks or performance slowdowns if large result sets are locked.
UPDATE
- keyword specifying exclusive row locksNO KEY UPDATE
- weaker exclusive lock that allows foreign-key updatesSHARE
- shared lock that blocks updates but not selectsKEY SHARE
- weakest lock, blocks row deletes and key updates onlyOF table_list
- optional, limit locks to listed tables in JOINsNOWAIT
- raise error if lock cannot be acquired immediatelySKIP LOCKED
- skip rows that are currently lockedSELECT, TRANSACTION, LOCK, NOWAIT, SKIP LOCKED, CURSOR, WITH TIES
SQL92 (FOR UPDATE added to the SELECT grammar)
It guarantees that no concurrent transaction can modify or delete the locked rows, but it does not protect against phantom rows unless your isolation level is SERIALIZABLE.
Yes, but the database will implicitly wrap the statement in a short transaction that ends immediately, releasing the lock as soon as the results are returned. Explicit transactions are recommended.
FOR SHARE places a shared lock. Other sessions can take the same shared lock and read the row but cannot update or delete it. FOR UPDATE uses exclusive locks that block both reads with FOR SHARE and all writes.
One session will acquire the row locks first. The second session will wait, raise an error (NOWAIT), or skip the locked rows (SKIP LOCKED) depending on the chosen modifier.