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 TRANSACTIONve všech databázích zapojených do distribuované transakce. -
Udělejte všechnu práci. Pokud se vyskytnou chyby,
ROLLBACKvšechny transakce. -
Spusťte
PREPARE TRANSACTIONna všech databázích. Pokud to kdekoli selže, spusťteROLLBACK PREPAREDv těch databázích, kde již byla transakce připravena, aROLLBACKna ostatních. -
Jakmile
PREPARE TRANSACTIONuspěl všude, spusťteCOMMIT PREPAREDna 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.