6

Supponiamo che tutti i database coinvolti in una transazione distribuita implementati con il commit a due fasi segnalino che sono pronti per il commit e dispongono dei blocchi necessari. Il coordinatore segnala di eseguire il commit e tutti i database eseguono la parte della transazione, ma un database SQL rileva un errore di divisione per zero a causa di una supervisione della programmazione che non considera tale possibilità. Dal momento che il coordinatore ha già segnalato l'impegno a tutti, cosa succede come risultato di tale divisione per zero?Il commit a due fasi protegge da errori di commit finali?

+0

Come e quando esattamente si aspetta che questo errore si verifichi? Presumo che un tale errore si verificherebbe durante la prima fase, causando un rollback. – Oded

+0

Significa che la definizione della fase di precommit è che ognuno esegue effettivamente la propria parte della transazione e che la fase di commit viene definita semplicemente scrivendo "" in un log ma il punto critico è che non si verifica alcuna esecuzione effettiva della transazione durante la fase di commit? Tutti gli articoli sul commit a due fasi che ho riscontrato non indicano mai esattamente quando ciascun database esegue la loro parte della transazione – user782220

+1

Bene, ciò che _actually_ accade è specifico dell'implementazione. Ma sì, sarebbe praticamente quello che succede (le modifiche sono fatte e l'unica cosa che i database distribuiti stanno aspettando è l'ack dal coordinatore per "chiudere l'affare" commettendo). – Oded

risposta

4

La seconda fase di commit normalmente non contiene codice utente che può fallire. I gestori delle risorse partecipanti devono garantire che non si possano verificare errori. Se questa garanzia viene violata, nessuna garanzia può essere fornita dal protocollo.

Il commit a due fasi tenta di risolvere Two Generals Problem. Non esiste una soluzione completa a questo problema. TPC è un'approssimazione.

Un altro modo in cui TPC può fallire è nel caso di una partizione di rete. Alcuni gestori risorse potrebbero eseguire il commit finale ma alcuni potrebbero non ricevere quel messaggio. Di nuovo, questo problema è irrisolvibile. Anche i tentativi non possono risolverlo.

È anche possibile attivare questo problema in condizioni reali: eseguire tutti i nodi partecipanti in uno stress test e tirare il cavo di rete in un punto arbitrario. Con alta probabilità i tuoi database distribuiti sono ora incoerenti perché alcuni messaggi di commit hanno perso un tempo molto scomodo.