Come garantire l'integrità dei dati (quando è coinvolto un sistema esterno)

5

Supponiamo di avere questa attività in un'applicazione composta da due parti:

1) Consegna di un file su un sistema esterno (non sotto il tuo controllo)
2) Una transazione di database nel nostro sistema, con informazioni su detta consegna (cosa è stato inviato, quando e da chi)

Se una qualsiasi di queste due parti fallisce, lo stato del nostro sistema sarà incoerente. Se un file è stato inviato e il db non ha informazioni su di esso, si tratta di un errore. Allo stesso modo, se il trasferimento del file non è riuscito, ma le informazioni nel database suggeriscono diversamente, anche questo è un errore.

Come ti avvicineresti a questa attività per assicurarti che il database sia lasciato in uno stato coerente dopo ogni volta che l'attività è tentata?

Sono inesperto nell'affrontare problemi come questo in un modo proprio - potrei sempre usare l'approccio ingenuo e far finta di scrivere sul database non fallirà mai. :-) Vorrei fare di meglio, però.

Le due variazioni di base che vedo qui lasciano a desiderare (pseudocodice):

A:

try:
    commitTransaction()
    deliverFile()
catch TransactionError:
    // No problem, delivery was never attempted.
catch DeliveryError:
    // The system will now say that it was delivered, 
    // even though it wasn't.

B:

try:
    deliverFile()
    commitTransaction()
catch TransactionError:
    // The system will now say nothing was delivered,
    // even though it was.
catch DeliveryError:
    // Easy enough to handle:
    rollbackTransaction()

Sono sicuro che esiste una soluzione accettabile e che non riesco a individuarlo?

    
posta perp 28.03.2011 - 20:16
fonte

2 risposte

3

Leggi il Protocollo di commit a due fasi e le tre fasi per avere un'idea di come affrontare i sistemi di database commerciali il problema che stai descrivendo. Quindi puoi usare quella conoscenza per modellare una soluzione.

Indipendentemente, avrai bisogno di un modo per eseguire una sorta di hash o CRC sui dati nel sistema esterno, altrimenti non sarai mai in grado di risolvere in modo affidabile lo stato del sistema. Se non riesci a fare un controllo di integrità dei file sul computer remoto, la tua sfida del programma è simile al Problema di due generali

    
risposta data 28.03.2011 - 20:36
fonte
0

Devi avere due diversi stati. Se hai le attività A e B. Il tuo stato dovrebbe indicare se è stata completata l'attività A o se l'attività A e B sono state completate.

Quindi al posto di:

deliverFile()
commitTransaction()

Dovresti avere qualcosa del tipo:

deliverFile()
setStatus('file delivered')
commitTransaction()
setStatus('complete')

In questo modo se il lavoro fallisce a metà o all'inizio è chiaro.

    
risposta data 28.03.2011 - 20:32
fonte

Leggi altre domande sui tag