Aller au contenu

SPRING BATCH & TRAITEMENTS MASSIFS - Exemple 2

Formation Java / Spring Boot – Traitements industriels & batch


Objectifs


1) Pourquoi Spring Batch ?

Dans un système bancaire, d’assurance ou de gestion complexe avec de gros fichiers à traiter périodiquement, le Batch est bienvenu pour :

Du coup, ces traitements :


2) API vs Batch – différence clé

On pourrait remplacer Temps réel par Synchrone dans le tableau ci-dessous :

API REST Batch
Temps réel Asynchrone
Utilisateur actif Traitement planifié
Petits volumes Gros volumes
Réponse immédiate Traitement long

Spring Boot gère l’API et Spring Batch gère les traitements lourds.


3) Architecture Spring Batch

Un traitement batch est structuré ainsi :

Job
 └── Step
      ├── ItemReader
      ├── ItemProcessor
      └── ItemWriter

3.1 Job

Le Job représente un traitement complet (Calcul intérêts journaliers).


3.2 Step

Le Step est une étape d’un job et peut correspondre à :


3.3 Reader / Processor / Writer


4) Dépendance Maven

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

5) Exemple concret – Calcul d’intérêts journaliers

Cas métier, chaque nuit vous devez :


6) Configuration de base

@Configuration
@EnableBatchProcessing
public class BatchConfig {
}

7) ItemReader – lecture en base

@Bean
public JpaPagingItemReader<CompteEpargne> reader(EntityManagerFactory emf) {
    JpaPagingItemReader<CompteEpargne> reader = 
        new JpaPagingItemReader<>();

    reader.setEntityManagerFactory(emf);
    reader.setQueryString("SELECT c FROM CompteEpargne c");
    reader.setPageSize(10);

    return reader;
}

8) ItemProcessor – logique métier

@Bean
public ItemProcessor<CompteEpargne, CompteEpargne> processor() {
    return compte -> {
        BigDecimal taux = new BigDecimal("0.01");
        BigDecimal interet = compte.getSolde().multiply(taux);
        compte.crediter(interet);
        return compte;
    };
}

9) ItemWriter – sauvegarde

@Bean
public JpaItemWriter<CompteEpargne> writer(EntityManagerFactory emf) {
    JpaItemWriter<CompteEpargne> writer = new JpaItemWriter<>();
    writer.setEntityManagerFactory(emf);
    return writer;
}

10) Définition du Step (étape)

Encore le pattern Builder.

@Bean
public Step calculInteretsStep(
        JobRepository jobRepository,
        PlatformTransactionManager transactionManager,
        ItemReader<CompteEpargne> reader,
        ItemProcessor<CompteEpargne, CompteEpargne> processor,
        ItemWriter<CompteEpargne> writer) {

    return new StepBuilder("calculInteretsStep", jobRepository)
        .<CompteEpargne, CompteEpargne>chunk(10, transactionManager)
        .reader(reader)
        .processor(processor)
        .writer(writer)
        .build();
}

11) Définition du Job

@Bean
public Job calculInteretsJob(JobRepository jobRepository, Step calculInteretsStep) {

    return new JobBuilder("calculInteretsJob", jobRepository)
        .start(calculInteretsStep)
        .build();
}

12) Comprendre le chunk

.chunk(10, transactionManager)

Signifie :


13) Gestion des erreurs

Vous devez ajouter :

.faultTolerant()
.skip(Exception.class)
.skipLimit(5)

Cela permet de :


14) Travaux pratiques


TP 1 – Batch intérêts journaliers


TP 2 – Gestion d’erreur contrôlée

Consignes :


TP 3 – Batch export CSV ou autre

Objectif :

@Bean
public FlatFileItemWriter<Compte> csvWriter() {
    FlatFileItemWriter<Compte> writer = new FlatFileItemWriter<>();
    writer.setResource(new FileSystemResource("comptes.csv"));
    writer.setLineAggregator(compte -> compte.getNumero() + ";" + compte.getSolde());
    return writer;
}

TP 4 – Batch import CSV

Objectif :

Reader CSV ci-dessous :

@Bean
public FlatFileItemReader<CompteDTO> csvReader() {
    FlatFileItemReader<CompteDTO> reader = 
        new FlatFileItemReader<>();
    reader.setResource(new FileSystemResource("input.csv"));
    return reader;
}

15) Gestion transactionnelle avancée

Pour chaque chunk :

Spring Batch stocke l’état en base :

Tables :

La reprise après crash est possible !


16) Tests des Batch


17) Erreurs fréquentes

  1. Chunk trop grand
  2. Mauvaise gestion de la mémoire
  3. Logique métier dans Reader
  4. Oublier la gestion d’erreurs
  5. Ne pas tester sur un gros volume de données
  6. Confondre batch et REST
  7. Ignorer les logs
  8. Mauvaise configuration transactionnelle
  9. Ne pas surveiller la erformance
  10. Sous-estimer la complexité en prod

18) État de votre projet

Votre projet est désormais :


Synthèse

Vous savez maintenant :


Prochainement

On abordera (optionnel) :