sql >> Databáze >  >> RDS >> PostgreSQL

Atomic UPDATE .. SELECT v Postgresu

Zatímco Erwinův návrh je možná nejjednodušší způsob, jak získat správné chování (pokud zopakujete transakci, pokud získáte výjimku pomocí SQLSTATE z 40001), aplikace ve frontě svou povahou mají tendenci pracovat lépe s blokováním požadavků, aby se dostaly na řadu ve frontě, než s implementací PostgreSQL SERIALIZABLE transakce, což umožňuje vyšší souběžnost a je poněkud "optimističtější" ohledně možnosti kolize.

Příklad dotazu v otázce tak, jak je, ve výchozím nastavení READ COMMITTED úroveň izolace transakce by umožnila dvě (nebo více) souběžná připojení k oběma "nárokovat" stejný řádek z fronty. Stane se toto:

  • T1 se spustí a dostane se až k uzamčení řádku v UPDATE fáze.
  • T2 se v době provádění překrývá s T1 a pokouší se aktualizovat tento řádek. Blokuje čekající na COMMIT nebo ROLLBACK z T1.
  • T1 provede potvrzení po úspěšném "nárokování" řádku.
  • T2 se pokusí aktualizovat řádek, zjistí, že T1 již má, hledá novou verzi řádku, zjistí, že stále splňuje kritéria výběru (což je právě to id zápasy) a také „nárokuje“ řádek.

Může být upraven tak, aby fungoval správně (pokud používáte verzi PostgreSQL, která umožňuje FOR UPDATE klauzule v dílčím dotazu). Stačí přidat FOR UPDATE na konec dílčího dotazu, který vybere id, a stane se to:

  • T1 spustí a nyní uzamkne řádek před výběrem id.
  • T2 se překrývá s T1 v době provádění a blokuje při pokusu o výběr ID, dokud nebude COMMIT nebo ROLLBACK z T1.
  • T1 provede potvrzení po úspěšném "nárokování" řádku.
  • V době, kdy bude T2 schopen číst řádek, aby viděl ID, vidí, že byl nárokován, takže najde další dostupné ID.

Na stránce REPEATABLE READ nebo SERIALIZABLE úroveň izolace transakce, konflikt zápisu by vyvolal chybu, kterou byste mohli zachytit a určit, že šlo o selhání serializace na základě SQLSTATE, a zkuste to znovu.

Pokud obecně chcete SERIALIZAČNÍ transakce, ale chcete se vyhnout opakovaným pokusům v oblasti fronty, můžete toho dosáhnout pomocí poradního zámku.



  1. Mechanismy pro sledování změn schématu DB

  2. Vkládání dat SQL Serveru do Salesforce.com

  3. SQL Server - vnitřní spojení při aktualizaci

  4. MariaDB JSON_REMOVE() Vysvětleno