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

Použití dvoufázových commitů na postgresu

Myslím, že jste špatně pochopili PREPARE TRANSACTION .

Tento příkaz ukončí práci na transakci, to znamená, že by měl být vystaven po veškerá práce je hotová. Myšlenka je taková, že PREPARE TRANSACTION dělá vše, co by mohlo potenciálně selhat během odevzdání, kromě samotného odevzdání. To má zaručit, že následný COMMIT PREPARED nemůže selhat.

Myšlenka je, že zpracování je následující:

  • Spusťte START TRANSACTION ve všech databázích zapojených do distribuované transakce.

  • Udělejte všechnu práci. Pokud se vyskytnou chyby, ROLLBACK všechny transakce.

  • Spusťte PREPARE TRANSACTION na všech databázích. Pokud to kdekoli selže, spusťte ROLLBACK PREPARED v těch databázích, kde již byla transakce připravena, a ROLLBACK na ostatních.

  • Jakmile PREPARE TRANSACTION uspěl všude, spusťte COMMIT PREPARED na všech zúčastněných databázích.

Tímto způsobem můžete zaručit „vše nebo nic“ v několika databázích.

Jednou důležitou součástí, kterou jsem zde nezmínil, je správce distribuovaných transakcí . Je to software, který si trvale pamatuje, kde se ve výše uvedeném algoritmu zpracování aktuálně nachází, aby mohl po havárii vyčistit nebo pokračovat v provádění.

Bez správce distribuovaných transakcí nemá dvoufázové potvrzování velkou cenu a je vlastně nebezpečné:pokud se transakce zaseknou v „připravené“ fázi, ale ještě nejsou potvrzeny, budou nadále držet zámky a (v případě PostgreSQL) blokuje práci autovakuování i přes restartování serveru , protože takové transakce musí být trvalé.

To je těžké napravit.




  1. GROUP BY interval překrývající se časové razítko MySQL dotaz

  2. Nastavení atributů připojení ODBC bez nutnosti psát kód

  3. zřetězená funkce s parametrem kurzoru oracle

  4. Symfony:Doctrine data fixture:jak zacházet s velkým souborem csv?