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ťteROLLBACK PREPARED
v těch databázích, kde již byla transakce připravena, aROLLBACK
na ostatních. -
Jakmile
PREPARE TRANSACTION
uspěl všude, spusťteCOMMIT 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.