sql >> Database >  >> RDS >> PostgreSQL

Consistentie in postgresql met vergrendeling en selecteren voor update

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;

Dit lijkt te werken in Read Committed. Het is alleen sql (hetzelfde als uw code) en kan in één aanroep (sneller) worden uitgevoerd.

@Seth Robertson:Het is niet veilig zonder LOCK TABLE en zonder while-lus.

Als er tegelijkertijd transactie A en transactie B zijn:A selecteert de eerste rij en B selecteert de eerste rij. A zal de rij vergrendelen en bijwerken, B moet wachten tot A zich commit. Dan zal B de voorwaarde job_name IS NULL opnieuw controleren. Het is niet waar en B wordt niet bijgewerkt - B zal de volgende rij niet selecteren, maar zal alleen opnieuw controleren en een leeg resultaat retourneren.

@joegester:SELECT FOR UPDATE is niet het probleem, want alle tafels zijn vergrendeld.

Misschien is er een andere manier om het werk te doen - als u rijen verwijdert en invoegt (in een andere tabel?) in plaats van NULL in te stellen. Maar ik weet niet zeker hoe.



  1. Postgresql wijst een select-query toe aan variabele in de functie

  2. Verbinding met Google Cloud PostgreSQL via JDBC met SSL

  3. Londiste-replicatie met PostgreSQL 9.0

  4. Hoe MySQL 8 op Ubuntu 20.04 LTS te installeren