定时任务更新数据库---非常规思路

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

思路

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;
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章