Falta pouco!

0 dias

0 horas

0 min

0 seg

1
resposta

Chunk variável

Boa noite!

Eu conseguiria definir um chunk por tamanho do arquivo? Por ex, quero processar meu arquivo inteiro, se der erro, quero que dê rollback em tudo.
Mas meu arquivo pode ter um tamanho variável.

Como seria o código?

Obrigado!

1 resposta

Bom dia!

No Spring Batch, o parâmetro do chunk() precisa ser um número fixo (int), porque ele define o tamanho da transação em lote. Não existe suporte nativo para passar um valor variável, como “tamanho do arquivo” diretamente.

Se você quer que todo o arquivo seja processado dentro de uma única transação (ou seja, rollback geral em caso de erro), a estratégia é simples:

  • Descobrir dinamicamente o tamanho do arquivo (quantidade de registros).
  • Passar esse valor como o tamanho do chunk.

Exemplo de como ficaria:

@Configuration
public class ImportacaoJobConfiguration {

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean
    public Step passoInicial(ItemReader<Importacao> reader,
                             ItemWriter<Importacao> writer,
                             JobRepository jobRepository) {

        int totalRegistros = calcularTotalRegistrosDoArquivo("meu-arquivo.csv");

        return new StepBuilder("passo-inicial", jobRepository)
            .<Importacao, Importacao>chunk(totalRegistros, transactionManager) // tamanho do arquivo
            .reader(reader)
            .writer(writer)
            .build();
    }

    private int calcularTotalRegistrosDoArquivo(String caminhoArquivo) {
        try (Stream<String> linhas = Files.lines(Paths.get(caminhoArquivo))) {
            return (int) linhas.count();
        } catch (IOException e) {
            throw new IllegalStateException("Erro ao ler arquivo para calcular total de registros", e);
        }
    }
}

o chunk será exatamente do tamanho do arquivo, ou seja, o commit só acontece no final. Se houver erro, o rollback será global.

Alternativas :

  • Se o arquivo for muito grande, esse approach pode estourar memória, já que o Spring Batch segura tudo até o commit. Nesse caso, talvez seja melhor manter chunks menores e implementar rollback manual (ex.: remover os registros já persistidos em caso de falha).
  • Outra opção é usar transaction boundaries customizados, mas isso foge do uso padrão do chunk().