Como garantir a integridade dos dados (quando um sistema externo está envolvido)

5

Digamos que você tenha essa tarefa em um aplicativo composto de duas partes:

1) Entrega de um arquivo para um sistema externo (não em seu controle)
2) Uma transação de banco de dados em nosso sistema, com informações sobre a referida entrega (o que foi enviado, quando e por quem)

Se qualquer uma dessas duas partes falhar, o estado do nosso sistema será inconsistente. Se um arquivo foi enviado e o banco de dados não tiver informações sobre ele, é um erro. Da mesma forma, se a transferência de arquivos falhou, mas as informações no banco de dados sugerem o contrário, isso também é um erro.

Como você abordaria essa tarefa para garantir que o banco de dados permanecesse em um estado consistente após cada vez que a tarefa fosse tentada?

Sou inexperiente em lidar com problemas como esse de uma maneira correta - sempre posso usar a abordagem ingênua e fingir que escrever no banco de dados nunca falhará. :-) Eu desejo fazer melhor que isso, no entanto.

As duas variações básicas que vejo aqui ambas deixam algo a desejar (pseudocódigo):

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()

Tenho certeza de que há uma solução aceitável para isso e que simplesmente não consigo identificar?

    
por perp 28.03.2011 / 20:16
fonte

2 respostas

3

Leia sobre o Protocolo de confirmação de duas fases e as três fases para ter uma ideia de como os sistemas de bancos de dados comerciais lidam o problema que você está descrevendo. Então você pode usar esse conhecimento para modelar uma solução.

Independentemente disso, você precisará de alguma forma de realizar algum tipo de hash ou CRC nos dados do sistema externo, caso contrário, você nunca conseguirá resolver com segurança o estado do sistema. Se você não pode fazer uma verificação de integridade de arquivos na máquina remota, seu desafio com o programa se assemelha ao Problema de dois generais

    
por 28.03.2011 / 20:36
fonte
0

Você precisa ter dois status diferentes. Se você tiver as tarefas A e B. Seu status deve indicar se apenas a tarefa A foi concluída ou se as tarefas A e B foram concluídas.

Então, no lugar de:

deliverFile()
commitTransaction()

Você deve ter algo como:

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

Desta forma, se o trabalho falhar no meio ou no início, fica claro.

    
por 28.03.2011 / 20:32
fonte

Tags