2010-06-10 12 views
9

Supponiamo che tu abbia un'applicazione che collega 3 diversi sistemi esterni. È necessario aggiornare qualcosa in tutto 3. In caso di errore, è necessario ripristinare le operazioni. Questa non è una cosa difficile da implementare, ma dire che l'operazione 3 fallisce, e quando si arretra, il rollback per l'operazione 1 fallisce! Ora il primo sistema esterno non è in uno stato ...Operazioni atomiche su diversi sistemi esterni senza transazione

Sto pensando che una possibile soluzione è chiudere l'applicazione e forzare una correzione manuale del sistema esterno, ma poi di nuovo ... Potrebbe già avere usato questa informazione (e forse è per questo che ha fallito), o potremmo non avere accesso sufficiente. Oppure potrebbe non essere nemmeno un buon modo per ripristinare l'azione!

Esistono alcuni modi per gestire questi casi?

EDIT: Alcuni dettagli dell'applicazione ..

Si tratta di un'applicazione multi utente web. La maggior parte del lavoro viene eseguita con i lavori pianificati (tramite Quartz.Net), quindi la maggior parte delle operazioni viene eseguita nella propria thread. Tuttavia, alcune azioni dell'utente dovrebbero attivare processi che aggiornano diversi sistemi. I sistemi esterni sono alquanto instabili.

stavo pensando di cambiare l'applicazione per utilizzare il comando e l'unità di modello di lavoro

+0

I sistemi esterni sono stati riparati? O puoi modificarli? – bmargulies

risposta

1

Il commit a due fasi (2PC) potrebbe essere adatto qui.

La prima fase consiste nel far sì che i vari database concordino di essere pronti a procedere con il commit. Nel tuo esempio, il database 1 non procederà con la scrittura finché non sarà sicuro che tutti e tre i database abbiano segnalato che la transazione sarà possibile.

Questo confronto con il processo che si sta descrivendo è un approccio "ottimistico": il Database 1 presupporrà che la transazione venga eseguita fino a quando non impara diversamente e viene forzata al rollback.

+0

Grazie. È un po 'quello che ho già utilizzato con UnitOfWork con Execute, Commit e Rollback che memorizza i comandi con CanProcess Do e Undo. – simendsjo

0

A seconda della dimensione della domanda (singolo utente vs impresa), chiudendo l'applicazione potrebbe essere una cattiva idea.

Prima di tutto, suggerirei di salvare lo stato iniziale delle informazioni che vengono cambiate nelle 3 app esterne nello spazio locale della propria app. Ciò significa che è possibile determinare almeno quale dovrebbe essere lo stato di rollback in caso di arresto anomalo dell'applicazione/rollback/ecc. Una volta che la transazione è stata eseguita correttamente, puoi cancellare questi dati.

Cosa fare quando una delle operazioni non riesce dipende dalla funzionalità dei 3 sistemi esterni. Supponiamo che uno di questi sistemi contenga i dati dei dipendenti. Chiudere l'applicazione semplicemente perché l'indirizzo di un dipendente è errato a causa di una transazione fallita è eccessivo. È molto meglio controllare semplicemente il log delle transazioni fallite (ad esempio, la memoria locale in cui sono stati salvati gli stati iniziali delle 3 app esterne) ogni volta che si accede ai dati di un dipendente. Se i dati dei dipendenti vengono contrassegnati come non validi, genera un errore che indica che il record è in uno stato non valido e non può essere recuperato.

Tuttavia, se l'intero sistema esterno sarà messo in disarmo da una transazione fallita, allora sì - non c'è niente che puoi fare qui, ma spegnere l'app fino a quando il problema non viene risolto.

1

Volete spiegare ulteriormente come il rollback dell'operazione 1 potrebbe fallire?

Lo stato a cui mira è quello in cui si trovava prima, quindi dovrebbe essere logicamente coerente.Potrebbero esserci problemi transitori come errori di rete, ma potrebbe essere il caso in cui il modo migliore per affrontarli è riprovare fino a quando i problemi non scompaiono.

Se il problema è che le transazioni successive hanno bloccato o modificato i dati nel frattempo, si verifica un problema molto più grande: le transazioni non sono atomiche e il rollback può rendere non valido l'output di altre transazioni.

0

La risposta di Oddthinking è buona, ma limitata perché è molto difficile effettivamente effettuare il in 2PC. Questo è stato conosciuto nella comunità di calcolo distribuito per un po 'di tempo, anche se molte persone fanno del loro meglio per ignorarlo.

Se sei interessato a esplorare più a fondo quest'area, il Paxos consensus algorithm è un buon punto di partenza. E sappi che questo è un problema sorprendentemente difficile, proprio a causa sia dei problemi a cui alludi sia del fatto che è davvero impossibile costruire un sistema di messaggistica veramente affidabile in grado di consegnare un messaggio in un lasso di tempo limitato. (Per capire perché è vero, considera che someone with a backhoe potrebbe cancellare tutti i collegamenti di rete tra le varie parti comunicanti ...)

Ho il sospetto che la vera soluzione sia progettare l'architettura del sistema generale e il modo in cui si eseguono le modifiche attraverso di esso che una perdita di comunicazioni in un'area non è catastrofica. Questo potrebbe o potrebbe non essere facile da fare, a seconda dei dettagli esatti.

Problemi correlati