码迷,mamicode.com
首页 > 其他好文 > 详细

分布式部署应用时主从同步时候主键重复

时间:2017-04-18 16:05:16      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:++   put   factory   warning   warnings   列表   static   integer   ida   

原因:

解决方法: 用redis生成主键

/**
     * 
     * @Title: getContractId
     * @user: zzx
     * @time: 2016年11月15日下午5:36:15
     * //DESC 获取订单ID
     * @param param step:步长
     * @return 当前分布式环境下最新ID
     * @return String  返回类型
     * @throws
     */
    public String getContractId(JSONObject param){
    	int step = param.getIntValue("step");
    	Long current = productContractIdAutomic.longValue();
    	Long newValue = current + step;
    	productContractIdAutomic.compareAndSet(current, newValue);
    	ResultInfo rs = new ResultInfo();
    	rs.setResult_code(0);
        rs.setResult_detail("success");
        rs.setResult_data(String.valueOf(current));
        return JSON.toJSONString(rs);
    }

全部代码:

package com.eshore.ismp.cache.processor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.eshore.ismp.cache.redis.RedisService;
import com.eshore.ismp.common.entity.ResultInfo;

/**
 * 订单模块缓存接口.
 * @author zhangjunyong
 * @version V1.0  2016/9/2 12:04
 */
@Service
public class ContractProcessor {
    private static final Logger logger = Logger.getLogger(ContractProcessor.class);

    private static final String KEY = "key";

    private static final String VALUE = "value";

    private static final String SIZE = "size";
    
    @Autowired
    RedisService redisService;
    
    @Resource(name="productContractIdAutomic")
	private RedisAtomicLong productContractIdAutomic;
    

    /**
     * 订单模块,用于存放数据进list.
     * @param param
     * @return String
     * @author zhangjunyong
     * @date 2016/9/2 12:05
     */
    public String putToList(JSONObject param) {
        ResultInfo rs = new ResultInfo();
        try {
            String key = param.getString(KEY);
            JSONArray array = param.getJSONArray(VALUE);
            if (array == null || array.isEmpty() || StringUtils.isEmpty(key)) {
                logger.error("参数错误");
                rs.setResult_code(4501);
                rs.setResult_detail("参数错误");
                return JSON.toJSONString(rs);
            }
            List<String> valueList = new ArrayList<String>();
            for (Object value : array) {
                valueList.add(String.valueOf(value));
            }
            long result = redisService.rpush(key, valueList);

            rs.setResult_code(0);
            rs.setResult_detail("success");
            rs.setResult_data(String.valueOf(result));
            return JSON.toJSONString(rs);
        } catch (Exception e) {
            rs.setResult_code(4502);
            rs.setResult_detail("系统错误!");
            logger.info("An error occur when invoke method putToList", e);
            return JSON.toJSONString(rs);
        }
    }

    /**
     * 批量弹出列表中数据.
     * @param param
     * @return String
     * @author zhangjunyong
     * @date 2016/9/2 12:06
     */
    @SuppressWarnings("rawtypes")
    public String getFromList(JSONObject param) {
        ResultInfo rs = new ResultInfo();
        try {
            String key = param.getString(KEY);
            int size = param.getInteger(SIZE);
            if (StringUtils.isEmpty(key) || size == 0) {
                logger.error("参数错误");
                rs.setResult_code(4501);
                rs.setResult_detail("参数错误");
                return JSON.toJSONString(rs);
            }

            List data = redisService.lpop(key, size);
            rs.setResult_code(0);
            rs.setResult_detail("success");
            rs.setResult_data(JSON.toJSONString(data));
            return JSON.toJSONString(rs);
        } catch (Exception e) {
            rs.setResult_code(4502);
            rs.setResult_detail("系统错误!");
            logger.info("An error occur when invoke method getFromList", e);
            return JSON.toJSONString(rs);
        }
    }

    /**
     * 批量存放hash对象到key中.
     * @param param
     * @return String
     * @author zhangjunyong
     * @date 2016/9/2 12:06
     */
    public String putToHash(JSONObject param) {
        String key = param.getString(KEY);
        JSONArray array = param.getJSONArray(VALUE);
        ResultInfo rs = new ResultInfo();
        if (array == null || array.isEmpty() || StringUtils.isEmpty(key)) {
            logger.error("参数错误");
            rs.setResult_code(4501);
            rs.setResult_detail("参数错误");
            return JSON.toJSONString(rs);
        }
        Map<String, String> valueMap = new HashMap<String, String>();
        for (Object value : array) {
            JSONObject jsObj = JSON.parseObject(String.valueOf(value));
            logger.info("jsonObj : = " + jsObj.toJSONString());
            logger.info("key=" + jsObj.getString("key") + " value=" + jsObj.getString("value"));
            valueMap.put(jsObj.getString("key"), jsObj.getString("value"));
        }
        int result = redisService.hmset(key, valueMap);

        rs.setResult_code(0);
        rs.setResult_detail("success");
        rs.setResult_data(String.valueOf(result));
        return JSON.toJSONString(rs);
    }
    
    /**
     * 
     * @Title: getContractId
     * @user: zzx
     * @time: 2016年11月15日下午5:36:15
     * //DESC 获取订单ID
     * @param param step:步长
     * @return 当前分布式环境下最新ID
     * @return String  返回类型
     * @throws
     */
    public String getContractId(JSONObject param){
    	int step = param.getIntValue("step");
    	Long current = productContractIdAutomic.longValue();
    	Long newValue = current + step;
    	productContractIdAutomic.compareAndSet(current, newValue);
    	ResultInfo rs = new ResultInfo();
    	rs.setResult_code(0);
        rs.setResult_detail("success");
        rs.setResult_data(String.valueOf(current));
        return JSON.toJSONString(rs);
    }
}

调用方法

package com.eshore.ismp.contract.sql;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eshore.ismp.common.entity.ResultInfo;
import com.eshore.ismp.common.thrift.CacheService.Iface;

@Component
@Scope("prototype")
public class IDManager {
	private static final Logger logger = Logger.getLogger(IDManager.class);
	
	@Autowired
	private Iface cacheServer;
	private static final int STEP = 200;
	private static String GET_ID_METHOD = "contract.getContractId";
	private Long current = 0L;
	private Long end = 0L;
	
	/**
	 * 
	 * @Title: getId
	 * @user: zzx
	 * @time: 2016年11月15日下午7:45:52
	 * //DESC 通过缓存获取ID
	 * @param type
	 * @return
	 * @return Long  返回类型
	 * @throws
	 */
	public synchronized Long getId(final int type) {
		if (this.end <= this.current) {
			JSONObject param = new JSONObject();
			param.put("step", STEP);
			try {
				String resultInfo =cacheServer.process(GET_ID_METHOD, param.toJSONString());
				ResultInfo ri = JSON.parseObject(resultInfo, ResultInfo.class);
				if(ri.getResult_code() ==0){
					current =Long.parseLong(ri.getResult_data())+1;
					end = current + STEP;
				}
				
			} catch (Exception e) {
				logger.error("get id error:",e);
				return null;
			}
		}

		return this.current++;
	}
}

如果表中存在历史数据,则需要开个定时器将id初始值设置大一点或者直接在数据库改掉redis的初始值然后重启服务

 

分布式部署应用时主从同步时候主键重复

标签:++   put   factory   warning   warnings   列表   static   integer   ida   

原文地址:http://www.cnblogs.com/JAYIT/p/6727862.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!