需求:設置定時任務,將數據庫用戶名全稱按照固定規則更新用戶簡稱(新增一列);因爲在進行交易時,若併發量過大去處理會影響性能。
思路:
1. 使用do...while循環執行數據庫查詢,查詢語句加limit限制爲100條每次,循環更新每條記錄,當查詢的結束集不是100條時,認爲是最後一次查詢,退出while循環。
2.常規方式在項目中做定時任務:
@Scheduled(cron = "0/5 * * * * ? ") // 間隔5秒執行
考慮不使用這種方式,是因爲避免當多臺服務部署時,數據庫查詢結果會出現部分重複數據去循環再次更新,浪費資源消耗性能。
在服務器上做crontab任務,使用curl 命令發起http請求來訪問這部分邏輯;
#!/bin/bash
step=10 #間隔的秒數,不能大於60
for((i=0;i<60;i=(i+step)));do
curl http://localhost:8080/test_trans/job/updateName #訪問鏈接
sleep $step
done;
exit 0
package com.zcy.controller;
import com.zcy.dao.CmmCityNewMapper;
import com.zcy.dao.MerchantInfoMapper;
import com.zcy.dao.UpMerchantInfoMapper;
import com.zcy.model.MerchantInfo;
import com.zcy.model.UpMerchantInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
/**
* http定時任務
*/
@Controller
@RequestMapping(value = "/job")
public class CronTabController {
private static final Logger logger = LoggerFactory.getLogger(CronTabController.class);
@Resource
private UpMerchantInfoMapper upMerchantInfoMapper;
@Resource
private MerchantInfoMapper merchantInfoMapper;
@Resource
private CmmCityNewMapper cmmCityNewMapper;
@Value("${shield.key}")
private String shieldKey;
@RequestMapping(value = "/updateName",method = { RequestMethod.GET, RequestMethod.POST }, produces = "application/json;charset=UTF-8")
@ResponseBody
public void refreshMchNm() {
logger.info("refresh merchant name begin");
long startTm = System.currentTimeMillis();
int num = 0;
long startIndex = 0;
//刷新商戶表中商戶簡稱
try {
do{
List<UpMerchantInfo> list = upMerchantInfoMapper.selectForJob(startIndex);
if(list.size()>0){
for(UpMerchantInfo upMerchantInfo : list){
String upMchName2 = shieldMchNmByKey(upMerchantInfo.getUpMchName());
upMerchantInfo.setUpMchName2(upMchName2);
logger.info("update upMchName2,upMchNo is #{},upMchName2 is #{}",upMerchantInfo.getUpMchNo(),upMchName2);
upMerchantInfoMapper.updateUpMchNm2(upMerchantInfo);
}
num = list.size();
startIndex = list.get(list.size()-1).getId();
}
}while(num == 100);
logger.info("UpMerchantInfo update success.");
} catch (Exception e) {
logger.info("UpMerchantInfo update error.",e);
}
num = 0;
startIndex = 0;
//刷新商戶表中商戶簡稱
try {
do{
List<MerchantInfo> merchantInfoList = merchantInfoMapper.selectForJob(startIndex);
if(merchantInfoList.size()>0){
for(MerchantInfo merchantInfo : merchantInfoList){
String mchShortName2 = shieldMchNmByKey(merchantInfo.getMchShortName());
merchantInfo.setMchShortName2(mchShortName2);
logger.info("update mchShortName2,dyMchNo is #{},mchShortName2 is #{}",merchantInfo.getDyMchNo(),mchShortName2);
merchantInfoMapper.updateMchNm2(merchantInfo);
}
num = merchantInfoList.size();
startIndex = merchantInfoList.get(merchantInfoList.size()-1).getId();
}
}while(num == 100);
logger.info("MerchantInfo update success.");
} catch (Exception e) {
logger.info("MerchantInfo update error.",e);
}
long endTm = System.currentTimeMillis();
logger.info("refresh merchant name end, cost time #{}ms",endTm-startTm);
}
/**
* 根據關鍵字屏蔽商戶簡稱
* @param mchName
* @return
*/
private String shieldMchNmByKey(String mchName) {
List<String> names = cmmCityNewMapper.selectAllNm();
String[] keys = shieldKey.split(",");
for(String key : keys){
names.add(key);
}
for(String name : names){
if(mchName.contains(name)){
mchName = mchName.replaceAll(name,"");
logger.info("shielded mcnName is #{}",mchName);
}
}
return mchName;
}
}