Penso che tu abbia frainteso PREPARE TRANSACTION .
Tale dichiarazione termina il lavoro sulla transazione, ovvero dovrebbe essere rilasciata dopo tutto il lavoro è fatto. L'idea è che PREPARE TRANSACTION fa tutto ciò che potrebbe potenzialmente non riuscire durante un commit tranne il commit stesso. Questo per garantire che un successivo COMMIT PREPARED non può fallire.
L'idea è che l'elaborazione sia la seguente:
-
Esegui
START TRANSACTIONsu tutti i database coinvolti nella transazione distribuita. -
Fai tutto il lavoro. Se ci sono errori,
ROLLBACKtutte le transazioni. -
Esegui
PREPARE TRANSACTIONsu tutti i database. Se fallisce ovunque, eseguiROLLBACK PREPAREDsu quei database dove la transazione era già stata preparata eROLLBACKsugli altri. -
Una volta
PREPARE TRANSACTIONha avuto successo ovunque, eseguiCOMMIT PREPAREDsu tutti i database coinvolti.
In questo modo, puoi garantire "tutto o niente" su più database.
Un componente importante qui che non ho menzionato è il gestore delle transazioni distribuito . È un software che memorizza in modo persistente dove si trova attualmente l'elaborazione dell'algoritmo sopra in modo che possa ripulire o continuare a eseguire il commit dopo un arresto anomalo.
Senza un gestore delle transazioni distribuito, il commit in due fasi non vale molto, ed è effettivamente pericoloso:se le transazioni si bloccano nella fase "preparata" ma non sono ancora state impegnate, continueranno a mantenere i lock e (nel caso di PostgreSQL) blocca il lavoro di autovacuum anche attraverso il riavvio del server , poiché tali transazioni devono essere persistenti.
È difficile da correggere.