SELECT … FOR UPDATE
Informix®
Legacy BDL programs typically use a cursor with SELECT FOR UPDATE
to implement
pessimistic locking and avoid several users editing the same rows:
DECLARE cc CURSOR FOR
SELECT ... FROM tab WHERE ... FOR UPDATE
OPEN cc
FETCH cc <-- lock is acquired
...
CLOSE cc <-- lock is released
The row must be fetched in order to set the lock.
If the cursor is local to a transaction, the lock is released when the transaction ends. If the
cursor is declared WITH HOLD
, the lock is released when the cursor is closed.
SET LOCK MODE
instruction to define the lock wait
timeout:SET LOCK MODE TO { WAIT | NOT WAIT | WAIT seconds }
The
default mode is NOT WAIT
.PostgreSQL
With PostgreSQL, locks are released when closing the cursor or when the transaction ends.
PostgreSQL locking granularity is at the row level.
PostgreSQL supports the NOWAIT
keywoard after FOR UPDATE
, and
has the lock_timeout
session parameter to define a lock timeout.
Solution
The database interface is based on an emulation of an Informix engine using transaction logging. Therefore, opening a SELECT ... FOR
UPDATE
cursor declared outside a transaction will raise an SQL error -255 (not in
transaction).
When using the SET LOCK MODE TO .. WAIT
instruction, the PostgreSQL driver
converts this statement to an UPDATE pg_settings
command, to change the
lock_timeout
parameter. For more details, see Concurrency management.
FOR UPDATE
cursors are typically opened inside a
transaction block, in case of concurrent lock error, the current transaction cannot be continued.