Ir para o conteúdo
DedicatedPHP Contato

Como projetar transações em lote em importações PHP

Aprenda a escolher limites transacionais, registrar checkpoints e retomar importações PHP sem duplicar alterações nem ocultar erros parciais.

Diagrama editorial de uma importação PHP dividida em lotes com transações, checkpoints e recuperação de erros

Uma importação extensa pode falhar por causa de uma conexão interrompida, um dado inválido ou um limite de tempo do processo. Se todas as alterações dependerem de uma única transação, o sistema poderá manter bloqueios por tempo demais e perder todo o trabalho confirmado apenas no final. Se, por outro lado, cada linha for salva de forma independente, sem um plano de recuperação, uma interrupção poderá deixar os dados incoerentes.

Projetar transações em lote em importações PHP consiste em escolher unidades de trabalho que possam ser confirmadas, registradas e repetidas com segurança. Isso não equivale a tornar toda a importação atômica: normalmente, cada lote é atômico por si só, e o processo completo pode ser aplicado parcialmente. Essa distinção deve se refletir tanto na implementação quanto na experiência operacional.

Por que uma única transação pode ser inadequada

Por que uma única transação pode ser inadequada — guía visual de DedicatedPHP

Uma transação longa pode manter bloqueios, aumentar a pressão sobre o log de transações e competir com as consultas da aplicação. Se a importação processar milhões de linhas, também será difícil saber quanto falta e o que fazer depois de uma falha. O comportamento exato depende do mecanismo de banco de dados, do nível de isolamento e do volume de gravações; por isso, convém medi-lo no ambiente real.

Confirmar cada linha reduz a duração de cada transação, mas pode multiplicar o custo das confirmações e deixar dependências entre linhas parcialmente aplicadas. O lote oferece um meio-termo: se uma operação do grupo falhar e a exceção se propagar, esse grupo será revertido; os lotes já confirmados permanecem. A aplicação deve comunicar isso como progresso parcial, não como sucesso global nem como rollback total.

Escolher o limite transacional adequado

A unidade não precisa ser sempre um número fixo de linhas. Ela deve representar alterações que possam ser validadas e persistidas de forma coerente. Se cada registro for independente, um lote de linhas pode ser suficiente. Se vários registros formarem uma entidade de negócio — por exemplo, um cabeçalho e suas linhas —, manter esse conjunto na mesma transação evita salvar uma entidade incompleta.

Para selecionar o tamanho, avalie a duração de cada lote, o volume de memória, a contenção em tabelas compartilhadas, a frequência de erros e o custo de repetir o trabalho. Um lote grande reduz o número de confirmações, mas leva mais tempo para ser processado e aumenta o trabalho que precisa ser refeito em caso de falha. Um lote pequeno limita esse custo, embora aumente a sobrecarga e possa prejudicar o desempenho. Não existe um tamanho universal: comece com um valor configurável e ajuste-o com testes de carga representativos.

No PHP, evite acumular o arquivo inteiro na memória se ele puder ser percorrido incrementalmente. Leia um grupo limitado de linhas, valide seus campos, inicie a transação, aplique as gravações e confirme. Se ocorrer um erro, reverta a transação do lote e classifique a falha. Com PDO, por exemplo, o controle pode ser expresso com beginTransaction(), commit() e rollBack(); o tratamento de exceções deve garantir que não se tente confirmar uma transação com falha.

Registrar o progresso para retomar com confiabilidade

Um checkpoint indica qual parte da origem foi processada e confirmada. Ele pode ser um identificador estável, uma posição em um arquivo ou uma chave composta, desde que permita continuar sem depender de uma ordem que possa mudar. Em uma consulta paginada, geralmente é mais seguro avançar por uma chave estável do que usar um deslocamento que possa mudar se registros forem inseridos ou removidos durante o processo.

O progresso e as alterações do lote devem ser coordenados. Quando viável, salve as gravações de negócio e o novo checkpoint na mesma transação. Assim, se o processo falhar antes da confirmação, não ficará registrado um avanço que o banco de dados não aplicou; se a transação for confirmada, o cursor também avançará. Se o estado da execução estiver em outro sistema, essa atomicidade não será automática: é preciso projetar uma reconciliação ou aceitar que os lotes serão repetidos e torná-los idempotentes.

Salve também o identificador da importação, seu estado, o checkpoint, os contadores e, quando apropriado, uma referência à versão ou à impressão digital do arquivo. Ao retomar, verifique se é a mesma entrada e se a execução pode ser recuperada. Defina estados explícitos, como pendente, em andamento, concluída e com falha, além de uma política para detectar execuções abandonadas. Evite marcar uma importação como concluída apenas porque o processo terminou sem lançar uma exceção: verifique se o final esperado foi alcançado.

Isolar erros e controlar as tentativas

Decida antecipadamente se um registro inválido deve interromper tudo, ser excluído ou ser marcado para revisão. Para erros de formato previsíveis, pode ser útil validar antes de abrir a transação e registrar o motivo junto com um identificador de linha. Para erros de persistência, reverta o lote afetado. Continuar com os lotes seguintes só é razoável se os dados forem independentes e a importação puder ser claramente declarada parcial.

Diferencie erros permanentes — como a ausência de um valor obrigatório — de falhas transitórias — como uma interrupção recuperável da conexão. Repetir uma tentativa após um erro permanente desperdiça recursos e dificulta o diagnóstico. Já uma nova tentativa após uma falha transitória pode usar um número limitado de tentativas e um intervalo crescente. Se o limite for atingido, preserve o estado e o contexto necessários para investigar e retomar sem ocultar a causa original.

As novas tentativas podem repetir gravações se não forem projetadas com cuidado. Use chaves de negócio ou identificadores da origem para reconhecer registros já importados e decida se uma repetição deve inserir, atualizar, ignorar ou sinalizar um conflito. Restrições de unicidade no banco de dados podem reforçar essa decisão, mas não substituem a lógica de negócio. Evite usar o checkpoint como único mecanismo contra duplicatas: ele pode ficar defasado ou não abranger alterações feitas por outros meios.

Se um lote também enviar e-mails, publicar mensagens ou chamar uma API, a transação do banco de dados não poderá desfazer esses efeitos externos. Não os execute como se fizessem parte de uma transação distribuída que não existe. Uma alternativa é registrar o evento pendente em uma tabela de saída transacional e processá-lo depois, com novas tentativas e identificadores idempotentes. Se o efeito externo falhar, o estado deve permitir recuperá-lo sem duplicar a operação nem afirmar que o lote foi totalmente concluído.

Testar consistência, progresso e recuperação

Os testes devem cobrir mais do que o caminho bem-sucedido. Injete falhas antes de iniciar uma transação, durante as gravações, imediatamente antes da confirmação e depois da confirmação, mas antes de atualizar qualquer estado externo. Verifique quais dados permanecem, qual checkpoint é preservado e se a retomada produz o resultado esperado. Inclua registros duplicados, linhas inválidas, lotes vazios e erros de persistência.

Em um teste representativo, meça a duração por lote, a memória, a taxa de erros, o tempo de bloqueio e o progresso. Verifique também se os contadores distinguem linhas lidas, aceitas, rejeitadas e confirmadas; «processadas» pode ser ambíguo se incluir alterações revertidas. As métricas e os logs devem identificar a importação e o lote, sem despejar dados confidenciais desnecessários para o diagnóstico.

Lista de verificação antes da produção

Lista de verificação antes da produção — guía visual de DedicatedPHP
  • A unidade transacional corresponde a uma unidade de negócio coerente.
  • O tamanho do lote é configurável e foi avaliado com dados e carga representativos.
  • O checkpoint só avança quando o lote correspondente é confirmado.
  • A estratégia de retomada usa uma chave estável e reconhece a entrada de origem.
  • Erros permanentes e transitórios têm tratamentos distintos e observáveis.
  • As operações repetidas são idempotentes ou detectam conflitos explicitamente.
  • Os efeitos externos são processados com uma estratégia independente e recuperável.
  • Os testes verificam falhas em diferentes pontos, não apenas a execução completa.

O objetivo não é impedir qualquer falha, mas limitar suas consequências e deixar explícito o estado resultante. Com limites transacionais bem definidos, checkpoints coerentes e novas tentativas seguras, uma importação PHP pode ser recuperada sem confundir progresso parcial com conclusão nem reaplicar alterações já confirmadas.

Deseja aplicar essas ideias ao seu projeto?Vamos discutir sua plataforma PHP.
Veja os serviços relacionados