PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Utilizzo di commit a due fasi su postgres

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, esegui ROLLBACK PREPARED su quei database dove la transazione era già stata preparata e ROLLBACK sugli altri.

  • Una volta PREPARE TRANSACTION ha avuto successo ovunque, esegui COMMIT 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.