场景
公司定时任务因数据量过大运行时间太久,大约3-4个小时,需要优化代码。数据量一旦变大,普通的修改操作也会变得复杂。
原代码
OpsPriceServiceImpl
1 |
|
mdmsPProductShopDao
1 | public void updateShopPrice(Long tenantNumId, Long dataSign, String cortNumId, String subUnitNumId, String itemNumId, |
mdmsPProductShopPriceLogDao
1 | public void updateShopLogNotValid(Long tenantNumId, Long dataSign,Long usrNumId,String cortNumId, |
问题
由以上代码可见,代码虽使用CompletableFuture.runAsync()
进行异步执行,但下方通过增强for循环单个进行修改操作,且调用的方法通过了if else
进行了多次判断,导致速度缓慢。
思路
第一个想法
通过将if else进行舍弃将其中sql拼接不通过priceType
进行判断,认真读代码后,发现是进行不同字段的修改,放弃。
第二个想法
将if else
改为switch
,同时将OpsPriceServiceImpl
中的增强for循环
改为stream流形式
。当数据量不超过10万条数据时,增强for循环
速度快,但超过时stream流形式
更为快速。
原OpsPriceServiceImpl
1 | for (MDMS_P_PRODUCT_SHOP_PRICE_LOG log : shopLogs) { |
改为
1 | shopLogs.stream().forEach(log->{ |
后发现stream流循环
通过parallelStream
可以进行并行操作,后将代码改为
1 | shopLogs.parallelStream().forEach(log->{ |
原updateShopPrice方法
1 | if (priceType == 501) { |
改为
1 | switch (priceType) { |
第三个想法
虽效率提高了部分,但感觉还是不够满意。原代码修改操作通过jdbcTemplate.update()
进行单条处理,决定通过jdbcTemplate.batchUpdate()
进行批量处理。因每循环一次需要对两个方法进行修改操作,可能会出现数据不统一问题,将这部分代码加入事务,出现异常后回滚(masterDataTransactionManager.getTransaction(TransactionUtil.newTransactionDefinition(300))
)。
修改后全部代码
OpsPriceServiceImpl
1 |
|
mdmsPProductShopDao
1 | public void batchUpdateShopPriceCase(Long tenantNumId, Long dataSign, StringBuilder sql, List<MDMS_P_PRODUCT_SHOP_PRICE_LOG> mdms_p_product_shop_price_logs) { |
mdmsPProductShopPriceLogDao
1 | public void batchUpdateShopLogNotValid(Long tenantNumId, Long dataSign, List<MDMS_P_PRODUCT_SHOP_PRICE_LOG> logList) { |