FolioPierEstudos de TI

Repetição, idempotência e reconciliação

Nota 36 de 37 · 6 min de leitura
Nesta página
  1. Uma tentativa não é uma operação de negócio
  2. Idempotência e controle de duplicidade
  3. O que cada evidência permite afirmar
  4. Repetição controlada
  5. Reconciliação entre o fornecedor e o sistema
  6. Eventos, fila e banco local

Uma chamada pode produzir efeito no fornecedor e terminar sem resposta no sistema da loja. Outra chamada pode receber a aprovação e falhar ao atualizar o banco local. Nos dois casos, tentar de novo exige saber qual etapa será repetida e como evitar uma segunda operação de negócio.

Uma tentativa não é uma operação de negócio

O pedido PED-0001 pode gerar uma operação de pagamento e várias tentativas de comunicação. Cada nível tem o próprio identificador:

  • Identificador do negócio: o pedido, a venda ou o documento que originou a operação.
  • Identificador da operação local: a intenção que o sistema acompanha até a conclusão.
  • Identificador da tentativa: a chamada específica, com início, duração e retorno próprios.
  • Identificador remoto: a cobrança, a pré-autorização ou o recurso criado no fornecedor.
  • Chave de idempotência: a identidade que o serviço usa para reconhecer uma repetição, quando o contrato oferece esse recurso.
  • Identificador do evento: o aviso que pode ser recebido ou entregue de novo.

Uma segunda tentativa pode ter outro identificador de requisição e manter a mesma chave de idempotência da intenção original. Um identificador de rastreio, usado no log, não impede a duplicidade. O número do pedido, sozinho, também não basta, porque o contrato define se um pedido admite vários pagamentos, cancelamentos ou tentativas comerciais diferentes.

Idempotência e controle de duplicidade

A idempotência mantém o mesmo efeito pretendido quando a operação é repetida. Uma criação por POST pode ter uma proteção específica, mas o método não oferece essa proteção por si. O contrato informa onde a chave vale, quais dados precisam continuar iguais, como as chamadas simultâneas são tratadas e por quanto tempo o serviço guarda o controle.

No gateway de pagamento, a primeira chamada e a repetição usam a chave operacao-0001 e os mesmos dados. A criação de uma chave operacao-0002 só porque a resposta da primeira demorou pode gerar outra cobrança. A reutilização da chave operacao-0001 depois de uma mudança no valor ou no destinatário também contraria o contrato.

Uma restrição de chave única no banco impede gravar duas vezes a mesma identidade, mas não resolve tudo quando o efeito e o registro da conclusão acontecem em momentos separados. Dois consumidores podem ver um registro como não tratado e prosseguir, e um terceiro pode aplicar o negócio e cair antes de registrar a conclusão. A implementação precisa coordenar a identidade, o efeito e a confirmação.

O que cada evidência permite afirmar

  • Falha de resolução do nome antes do envio: a tentativa não passou dessa etapa, e o histórico das outras tentativas e os intermediários ainda são conferidos.
  • Tempo esgotado à espera da resposta: o programa não recebeu o retorno no prazo, e o recebimento, o processamento e a situação no fornecedor continuam desconhecidos.
  • Recusa explícita da mesma operação: o retorno registra a recusa, e o motivo e o tratamento definido pelo fornecedor orientam o passo seguinte.
  • Aprovação remota com o pedido pendente na loja: existe uma divergência entre dois estados confirmados, e a aplicação local, o acompanhamento e a associação entre os registros são conferidos.

O resultado desconhecido descreve o que se sabe e não vira recusado só para liberar uma tela. Um tempo esgotado no programa, ou o cancelamento da espera, também não desfaz uma alteração feita no fornecedor.

Repetição controlada

Os erros passageiros podem admitir repetição, mas um erro de contrato, a falta de permissão e uma recusa comercial pedem outra decisão. O código, a mensagem e o contrato classificam o erro, e não existe uma lista universal de respostas que permitem repetir. Uma política de repetição limita a quantidade de tentativas e o tempo total com três recursos:

  • Backoff: a pausa entre as tentativas, que pode aumentar a cada falha, como em 1, 2 e 4 segundos, com os valores definidos pela integração;
  • Jitter: a variação aleatória da pausa, que evita que muitos clientes repitam ao mesmo tempo;
  • Retry-After: o tempo de espera informado pelo próprio serviço, quando a resposta traz esse cabeçalho.

A renovação da credencial pode recuperar o acesso, mas não muda o resultado de uma operação já enviada. As novas tentativas mantêm as identidades exigidas e registram os próprios retornos. Quando o serviço não oferece chave nem consulta confiável, o suporte não cria uma garantia de repetição, registra o resultado desconhecido e segue o procedimento do fornecedor para localizar, confirmar ou desfazer a operação.

Reconciliação entre o fornecedor e o sistema

A reconciliação compara os registros e as situações dos dois lados e regulariza as diferenças com evidências. A comparação começa pela mesma conta, loja, ambiente e operação. O identificador remoto, a referência de origem, o valor e a moeda confirmam a associação, e um horário próximo, sozinho, não basta.

Uma consulta que não encontra o recurso pode ter usado o ambiente errado, outro identificador, só uma página do resultado ou um momento anterior à disponibilização. Quando o recurso está pendente, o acompanhamento continua. Quando está confirmado, a atualização local é recuperada pelo procedimento apropriado. Quando há uma recusa conclusiva, o motivo orienta o passo seguinte.

Forçar uma situação ou criar outra cobrança não corrige a divergência. Reaplicar um retorno confirmado é diferente de repetir a criação remota, e o cancelamento e o estorno são operações novas, com identificação, permissão e regras próprias.

Eventos, fila e banco local

Confirmar uma entrega depois da gravação deixa uma janela para a reentrega de um trabalho já aplicado, e confirmar antes da gravação pode perder o trabalho quando a gravação falha. Dois controles de implementação tratam esse problema:

  • Inbox: o registro dos eventos recebidos e tratados, que impede aplicar o mesmo evento duas vezes;
  • Outbox: a gravação das mensagens a publicar na mesma transação da alteração local, para que a publicação aconteça depois, sem se perder.

A publicação feita a partir do outbox ainda pode se repetir, e o efeito remoto não entra na transação do banco local. Por isso, a proteção no consumidor e a reconciliação continuam necessárias. Esses controles fazem parte do desenho da integração, e a existência deles é confirmada antes de qualquer conclusão baseada neles.

No suporte

Diante de uma operação com resultado desconhecido, convém preservar a identidade da operação e de cada tentativa e confirmar a situação no fornecedor antes de qualquer repetição. Depois, a análise separa a recuperação da atualização local, o acompanhamento de uma pendência e uma operação comercial nova.

Para guardar

  • A operação de negócio e a tentativa de comunicação têm identidades diferentes.
  • O identificador de rastreio não protege contra a duplicidade.
  • A idempotência tem alcance, dados e prazo definidos pelo contrato.
  • O tempo esgotado à espera da resposta deixa o resultado remoto incerto.
  • A repetição precisa de limites, e a reconciliação precisa de uma associação confiável entre os registros.
Um POST de cobrança terminou em tempo esgotado, e o integrador gerou uma chave nova e conseguiu a aprovação. O que ainda falta investigar?

A situação da primeira operação. A chave nova pode ter criado outra cobrança, sem proteção contra a duplicidade em relação à anterior. As referências, os identificadores remotos, os valores e o contrato mostram se existem duas cobranças.

O pagamento está aprovado no fornecedor, mas o banco local não foi atualizado. É preciso criar o pagamento de novo?

Não. A associação entre o pedido e a cobrança é confirmada, e o resultado é aplicado no banco local pelo procedimento previsto. A criação remota já tem resultado conhecido, e uma nova cobrança aumentaria a divergência.

Publicado a partir do Obsidian · FolioPier