SELECT FOR UPDATE
Lock selected rows for the duration of a transaction to prevent concurrent modification.
SELECT FOR UPDATE FOR SHARE pessimistic locking row locking UPDLOCK
locking concurrency transaction pessimistic
| Database | Status | Syntax Family | Min Version |
|---|---|---|---|
| PostgreSQL | full | for-update | - |
| MySQL | full | for-update | - |
| MariaDB | full | for-update | - |
| Oracle | full | for-update | - |
| SQL Server | full | table-hints | - |
| SQLite | none | - | - |
| Redshift | none | - | - |
| DB2 | full | for-update | - |
| Snowflake | none | - | - |
| BigQuery | none | - | - |
Compare Databases
Database Details
PostgreSQL
full
SELECT id, balance FROM accounts WHERE id = 1 FOR UPDATE;- Supports FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE, and FOR KEY SHARE lock strengths.
- NOWAIT and SKIP LOCKED modifiers are available.
- OF table_name can be used to lock specific tables in a join.
MySQL
full
SELECT id, balance FROM accounts WHERE id = 1 FOR UPDATE;- Supports FOR UPDATE and LOCK IN SHARE MODE (legacy) / FOR SHARE (8.0+).
- NOWAIT and SKIP LOCKED modifiers added in MySQL 8.0.
- Locking applies only to rows in InnoDB tables.
MariaDB
full
SELECT id, balance FROM accounts WHERE id = 1 FOR UPDATE;- Supports FOR UPDATE and LOCK IN SHARE MODE.
- SKIP LOCKED added in MariaDB 10.6.
- Locking applies to InnoDB tables.
Docs: SELECT FOR UPDATE
Oracle
full
SELECT id, balance FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;- Supports FOR UPDATE [OF columns] [NOWAIT | WAIT n | SKIP LOCKED].
- OF clause allows locking rows from specific tables in a multi-table query.
- WAIT n specifies a timeout in seconds before raising an error.
Docs: SELECT FOR UPDATE
SQL Server
full
SELECT id, balance FROM accounts WITH (UPDLOCK, ROWLOCK) WHERE id = 1;- Uses table hints instead of a standard FOR UPDATE clause.
- WITH (UPDLOCK, ROWLOCK) acquires an exclusive row-level update lock.
- WITH (HOLDLOCK) holds a shared lock for the duration of the transaction.
- No standard SQL FOR UPDATE syntax is supported, but the locking capability is native.
SQLite
none
- SQLite uses file-level locking, not row-level locking.
- Concurrent writers are serialized at the database level.
- WAL mode allows one writer and multiple readers simultaneously but has no row-level lock semantics.
Redshift
none
- Redshift uses MVCC for concurrency control.
- There is no row-level locking mechanism.
- Writers and readers do not block each other through lock acquisition.
DB2
full
SELECT id, balance FROM accounts WHERE id = 1 FOR UPDATE WITH RR;- Supports FOR UPDATE WITH RR/RS/CS/UR to specify isolation level.
- SKIP LOCKED DATA clause is available.
- FOR READ ONLY can be specified to explicitly declare a non-locking cursor.
Snowflake
none
- Snowflake uses optimistic concurrency control.
- There is no SELECT FOR UPDATE mechanism.
- Transactions serialize at commit time using snapshot isolation.
Docs: Snowflake Transactions
BigQuery
none
- BigQuery does not support row-level locking.
- Multi-statement transactions use optimistic concurrency with serializable isolation at the table level.
Docs: BigQuery Transactions