Ik denk dat je PREPARE TRANSACTION
verkeerd hebt begrepen .
Die verklaring beëindigt het werk aan de transactie, dat wil zeggen dat deze na . moet worden uitgegeven al het werk is gedaan. Het idee is dat PREPARE TRANSACTION
doet alles wat mogelijk zou kunnen mislukken tijdens een commit behalve de commit zelf. Dat is om te garanderen dat een volgende COMMIT PREPARED
kan niet mislukken.
Het idee is dat de verwerking als volgt is:
-
Voer
START TRANSACTION
uit op alle databases die betrokken zijn bij de gedistribueerde transactie. -
Doe al het werk. Als er fouten zijn,
ROLLBACK
alle transacties. -
Voer
PREPARE TRANSACTION
uit op alle databanken. Als dat ergens niet lukt, voer danROLLBACK PREPARED
uit op die database waar de transactie al was voorbereid enROLLBACK
op de anderen. -
Eenmaal
PREPARE TRANSACTION
is overal gelukt, voerCOMMIT PREPARED
uit op alle betrokken databases.
Op die manier kunt u "alles of niets" garanderen in verschillende databases.
Een belangrijk onderdeel hier dat ik niet heb genoemd, is de gedistribueerde transactiemanager . Het is een stukje software dat voortdurend onthoudt waar in het bovenstaande algoritme de verwerking momenteel is, zodat het kan opschonen of doorgaan met committen na een crash.
Zonder een gedistribueerde transactiemanager is het vastleggen in twee fasen niet veel waard, en het is zelfs gevaarlijk:als transacties vast komen te zitten in de "voorbereide" fase maar nog niet zijn vastgelegd, blijven ze vergrendeld en (in het geval van PostgreSQL) autovacuüm werk blokkeren zelfs door opnieuw opstarten van de server , aangezien dergelijke transacties persistent moeten zijn.
Dit is moeilijk om goed te krijgen.