前言
通常情况下我们在系统中创建订单编号时,都会按照一定的规则去生成,因为订单编号是唯一的,不能重复的。
命名规则
例:业务编码+时间戳+流水号
方案
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; }