2017-02-13 24 views
0

在我的Spring Boot應用程序中,我試圖在後臺執行一些任務。Java Spring Boot - 用於在後臺運行的異步數據庫操作的CommandLineRunner

從一個數據庫獲取數據,並將其存儲在另一個數據庫中,每隔30分鐘保存一次。

使用@Async創建一個處理此問題的CommandLineRunner類會是正確的嗎?

@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

這不起作用,因爲它首先是一個內部方法調用(由於AOP的代理不起作用)。其次,你不能將'@ Async'應用於'static'方法。所以它根本無法工作。 「@ Scheduled」是爲此而發明的,不要試圖再次創建自己的。如果你有大量的數據,你可能需要考慮將其與Spring Batch結合起來。 –

回答

0

你可能會從引進Spring batch到你的應用程序中受益。目前,您對批次中發生的情況沒有太多的控制,例如在作業失敗時會發生什麼情況,或者應該同時處理多少個項目,或者應該在多線程環境中運行。

隨着Spring Batch的,你可以創建一個ItemReaderWagerBoardMarksRepo讀取,一個ItemProcessor你的實體轉化爲你的輸出和內StoreDbEntRepo存儲項目的ItemWriter。解釋這一切將會過於寬泛,但您可以閱讀他們的reference guide以開始使用。

要每30分鐘安排一次任務,您可以使用@Scheduled annotation。只需配置fixedDelay並使其運行批處理作業。或者,您也可以使用cron語法指定延遲。

一個例子:

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

計劃是這樣的操作進行,見下文

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

代碼不要忘記在你的啓動類使用@EnableScheduling

@SpringBootApplication 
@EnableScheduling 
public class Application { 

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

Scheduling Tasks春季文檔瞭解更多詳情。