zoukankan      html  css  js  c++  java
  • Redis的“原子性自增”在订单编号策略中的简单应用

    前言

    通常情况下我们在系统中创建订单编号时,都会按照一定的规则去生成,因为订单编号是唯一的,不能重复的。

    命名规则

    例:业务编码+时间戳+流水号

    方案

    1、传统方案,比较主流的就是在数据库创建一个序列号表(sequence),然后在生成订单的时候,先使用一个含有事务的存储过程从sequence表获取当前订单号,然后在生成订单。但是这种方案过于复杂,在并发的情况下,事务会影响订单的生成速度。

    2、Redis方案,首先Redis的原子性让我们可以不考虑并发的情况,利用原子性自增操作INCR时间计数器功能,再加上时间业务编码,时间戳此时就可生成一个流水号。

    代码实现:

    @Autowired
        private RedisTemplate redisTemplate;
    /***
         * redis自增
         * @param key
         * @return
         */
        public Object getIncrValue(final String key){
            ValueOperations<String, String> valueOper = redisTemplate.opsForValue();
            redisTemplate.setValueSerializer(new StringRedisSerializer());
            Object value = valueOper.increment(key,1);
            return value;
        }
    /***
         * redis清空之后,保存从数据库中取出的流水号
         * @param key
         * @param value
         */
        public void setIncrValue(final String key,final String value){
            ValueOperations<String, String> valueOper = redisTemplate.opsForValue();
            redisTemplate.setValueSerializer(new StringRedisSerializer());
            valueOper.set(key,value);
        }
    import org.springframework.data.redis.core.RedisTemplate;
    
    /***
         * 生成订单编号
         * @return
         */
        public String getOrderCode(long num) {
            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DAY_OF_MONTH);
    
            c.set(year, month - 1, day, 0, 0, 0);
    
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //数字长度9位,长度不够数字前面补0
            String serialNum = String.format("%09d", num);
            return N+ year + month + day + serialNum;
        }

     附:redisZset的使用

       //zSet
        public void zSet(final String key,final Object value,Double score){
            redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();  
            zSetOperations.add(key, value, score);
        }
        
        //取出Zset
        public Set zRange(final String key){
            redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();  
            
            Set result = null;
            try {
                result = zSetOperations.range(key, 0, zSetOperations.size(key));
            } catch (Exception e) {
                result = null;
                e.printStackTrace();
            }
            return result;
        }
        
    View Code
  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/4king/p/11814306.html
Copyright © 2011-2022 走看看