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.

Informix provides the 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.

Important: With PostgreSQL, if an SQL error occurs during a transaction block, the whole transaction is aborted. Since FOR UPDATE cursors are typically opened inside a transaction block, in case of concurrent lock error, the current transaction cannot be continued.