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 TRANSACTION
su tutti i database coinvolti nella transazione distribuita. -
Fai tutto il lavoro. Se ci sono errori,
ROLLBACK
tutte le transazioni. -
Esegui
PREPARE TRANSACTION
su tutti i database. Se fallisce ovunque, eseguiROLLBACK PREPARED
su quei database dove la transazione era già stata preparata eROLLBACK
sugli altri. -
Una volta
PREPARE TRANSACTION
ha avuto successo ovunque, eseguiCOMMIT PREPARED
su 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.