2017-02-13 1 views
0

Dans mon application de démarrage de printemps, j'essaie de faire quelques tâches en arrière-plan.Java Spring Boot - CommandLineRunner pour les opérations Async db qui s'exécute en arrière-plan

Obtention de données à partir d'une base de données et stockage dans une autre, toutes les 30 minutes.

Serait-il correct de créer une classe CommandLineRunner qui s'occupe de cela avec @Async?

@Component 
public class UpdateDB implements CommandLineRunner { 

@Autowired 
private WagerBoardMarksRepo loadRepo; 

@Autowired 
private StoreDbEntRepo storeRepo; 

@Async 
private static void update() { 
    while (true) { 

     // get data from loadRepo. 
     // save data to storeRepo 

     try { 
      Thread.sleep("sleep for 30min"); // 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

@Override 
public void run(String... args) throws Exception { 
    update(); 
} 

}

+0

Cela ne fonctionnerait pas parce que d'abord un appel de méthode interne (ne fonctionne pas en raison de proxies pour AOP). Deuxièmement, vous ne pouvez pas appliquer les méthodes '@ Async' aux méthodes' static'. Donc ça ne marchera tout simplement pas. '@ Scheduled' est inventé pour cela, n'essayez pas de créer le vôtre à nouveau. Si vous avez de grandes quantités de données, vous pouvez envisager de combiner cela avec Spring Batch. –

Répondre

0

Vous pouvez bénéficier de l'introduction Spring batch à votre application. Actuellement, vous n'avez pas beaucoup de contrôle sur ce qui se passe dans votre lot, comme ce qui se passe lorsque le travail échoue, ou combien d'éléments doivent être traités simultanément, ou doit-il s'exécuter dans un environnement multithread.

Avec Spring Batch, vous pouvez créer un ItemReader qui lit WagerBoardMarksRepo, un ItemProcessor qui convertit votre entité à votre sortie et un ItemWriter qui stocke des éléments dans StoreDbEntRepo. Expliquer tout cela serait trop large, mais vous pouvez lire leur reference guide pour commencer.

Pour planifier des tâches toutes les 30 minutes, vous pouvez utiliser le @Scheduled annotation. Il suffit de configurer le fixedDelay et de le faire exécuter le travail par lots. Vous pouvez également spécifier un délai en utilisant la syntaxe cron.

Un exemple:

@Scheduled(fixedDelay = 1800000) // 1000 millis * 1800 seconds = 30 minutes 
public void doBatch() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { 
    jobLauncher.run(batchJob, new JobParametersBuilder().toJobParameters()); 
} 
1

Scheduler est fait pour une telle opération, voir le code ci-dessous

@Component 
public class ScheduledTasks { 
    @Scheduled(cron = "0 0,30 * * * * ?") 
    public void update() { 
     // get data from loadRepo. 
     // save data to storeRepo 
    } 
} 

Et ne pas oublier d'utiliser @EnableScheduling dans votre classe de démarrage

@SpringBootApplication 
@EnableScheduling 
public class Application { 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class); 
    } 
} 

Voir le Scheduling Tasks docs de printemps pour plus de détails.