需求:设置定时任务,将数据库用户名全称按照固定规则更新用户简称(新增一列);因为在进行交易时,若并发量过大去处理会影响性能。
思路:
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;
}
}