PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Coerenza in postgresql con blocco e selezione per l'aggiornamento

BEGIN; 
LOCK TABLE slots IN ACCESS EXCLUSIVE MODE; 
UPDATE slots SET job_name = '111' WHERE id IN (SELECT id FROM slots WHERE job_name IS NULL LIMIT 1) RETURNING *;
COMMIT;

Questo sembra funzionare in Read Committed. È solo sql (come il tuo codice) e può essere eseguito in una chiamata (più veloce).

@Seth Robertson:non è sicuro senza LOCK TABLE e senza ciclo while.

Se sono presenti la transazione A e la transazione B contemporaneamente:A selezionerà la prima riga e B selezionerà la prima riga. A bloccherà e aggiornerà la riga, B dovrà attendere fino al commit di A. Quindi B ricontrollerà la condizione nome_lavoro IS NULL. È falso e B non si aggiornerà - B non selezionerà la riga successiva ma ricontrollerà solo e restituirà un risultato vuoto.

@joegester:SELECT FOR UPDATE non è il problema perché tutta la tabella è bloccata.

Forse c'è un altro modo per fare il lavoro:se elimini e inserisci righe (in un'altra tabella?) Invece di impostare NULL. Ma non sono sicuro di come.