今天鵬哥帶大家了解一下分區Step,按照鵬哥的套路,上來第一步肯定是一個例子,然後是例子的講解,最後是源碼分析為什麼會這樣設置。這樣才是由淺入深的學習一個知識點正確的套路。所以今天鵬哥帶給大家的是一個Step分區的例子。這是一個典型的資料庫分區處理的例子,如果你只想使用一下資料庫分區功能,看這個例子就足夠了。
程序猿最討厭沒有需求的例子,其實是因為不想費腦子想需求。哈哈,這個例子我們來假想有這麼一個需求:資料庫有100條記錄,我們分5片去處理它,也就是每片20條。同時Reader是分頁讀,每頁讀3條,設置chunkSize = 5,也就是每5條事務提交一次。好了,完美的需求,再次偷笑。既然有需求了,那我們就按部就班去實現這個需求吧。
Step 1: 創建一個Spring Batch 的工程
當然首先還是需要先創建一個Spring Batch 的工程,這裡鵬哥就不浪費了筆墨了,看這篇文章就好了。參考[SpringBatch從入門到放棄001- HelloWorld]。
Step 2: 定義我們的分片規則
回憶我們的需求,資料庫有100條記錄,需要分5片執行,怎麼個分法?這裡就需要對這100條記錄的數據結構有一定的了解了。因為鵬哥自己的建的測試數據,所以鵬哥知道這是一個ID連續的100條記錄,因此只要按照ID分就可以了。我們取ID最大值和最小值,將兩者相減就得到了總記錄數,將這個數字除以5,就可以得到每一片的數據集大小,當然這裡一眼就能看出來是20,鵬哥只是想模擬更真實的場景。
新建一個類,取名DbPartitioner 實現 Partitioner接口。Override partition()方法。方法的入參是需要分的片數,出參是每一片執行時的上下文。鵬哥在代碼裡面加了詳細的注釋,可以看下邊的代碼就可以了。
Step 3:定義Reader/Processor/Writer
我們使用JdbcPagingItemReader 作為我們分頁讀的Reader,按照ID排序,並設置PageSize=3。這裡跟之前不同的是我們傳入了兩個參數,這兩個參數就是第一步Partitioner中我們放到ExecutionContext中的值,因為Reader我們添加了@StepScope註解,所以我們可以在這裡直接注入這兩個值。
因為沒有其他要求,我們簡單定義Processor/Writer就好了。
Step 4 為了清晰的能看到每一片執行的數據和線程信息,我們定義了一個StepExecutionListener
之前鵬哥介紹過Listener的使用,這裡就不做過多地展開。參考[SpringBatch從入門到放棄004- Listener]。我們新建一個StepExecutionPartitionListener類,在beforeStep() 中列印當前線程名稱、當前Step 名稱和當前Step ExecutionContext 中的參數值,這個值會被注入到Reader中。
Step 5: 新建一個需要分片的Step
定義一個簡單的Step ,設置了Chunk信息,Reader/Processor/Writer以及綁定上一步定義的Listener。
Step 6: 新建一個PartitionHandler
這個才是這個例子的核心,我們定義了一個TaskExecutorPartitionHandler,並設置了線程池和需要分片的Step,最重要的是我們設置了GridSize ,這個值就是我們需要分的片數。設置5 就是分5片。
Step 7: 定義被Partitioner包裝的Step
我們定義一個PartitionStep用於包裝我們上邊定義的那個簡單Step,這個PartitionStep裡面我們設置了我們前邊定義的分片規則和分片之後的Handler。後邊組裝Job的時候使用的是這個PartitionStep。
Step 8:組裝一個Job
我們在第7步中,定義了一個包裝過的PartitionStep,這裡我們用這個Step 組裝一個Job。
Step 9:構建測試數據
我們新建了一個Junit ,這個測試類的目的是為了構建我們的測試數據,定一個JdbcTemplate ,並利用JdbcTemplate.batchUpdate() 方法批量的往測試資料庫中插入100條記錄,為了演示方便我們資料庫ID欄位設置了自增。
Step 10: 定義Junit 測試Job
這一步我們利用Spring Batch 4.0的新特性,構建一個Junit的測試類。如果你不知道@SpringBatchTest 有什麼用,不要著急,你先按照鵬哥的方式使用就好了,鵬哥會在後續文章中分享關於 Spring Batch 4.0裡面的新特性的。
Step 11: 分析測試結果
根據列印的日誌首先我們看到我們的系統幫我們起了5個線程,每個線程執行一個分片 Step,並輸出了每片裡面的參數。
同時我們在Writer 裡面也列印出來了當前的線程名稱和需要Writer的數據,我們通過日誌可以看出,輸出是亂序的,這樣進一步佐證了分片是多線程並發執行。
好了,這個資料庫分片執行的例子已經寫完了,因為排版問題,鵬哥統一使用了圖片,有需要源碼的朋友可以關注鵬哥,發私信找鵬哥要源碼。