sql >> Databasteknik >  >> RDS >> PostgreSQL

Konsistens i postgresql med låsning och välj för uppdatering

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;

Detta verkar fungera i Read Committed. Det är bara sql (samma som din kod) och kan köras i ett anrop (snabbare).

@Seth Robertson:Det är inte säkert utan LOCK TABLE och utan while-loop.

Om det finns transaktion A och transaktion B samtidigt:A väljer första raden och B väljer första raden. A kommer att låsa och uppdatera rad, B måste vänta tills A commit. Då kommer B att kontrollera villkoret jobbnamn ÄR NULL igen. Det är falskt och B kommer inte att uppdatera - B kommer inte att välja nästa rad utan kommer bara att kontrollera igen och returnera tomt resultat.

@joegester:VÄLJ FÖR UPPDATERING är inte problemet eftersom alla tabeller är låsta.

Kanske finns det ett annat sätt att göra jobbet - om du tar bort och infogar rader (i en annan tabell?) istället ställer du in NULL. Men jag är inte säker på hur.



  1. Handledning för formulär och rapporter för Oracle 9i, Oracle 10g och Oracle 11g Developer Suite

  2. Blanda ihop Connect by, inre join och summera med Oracle

  3. Distribuera Django till Heroku (Psycopg2-fel)

  4. Codeigniter, Join och Case When Query