1 前言
在系统中,为了区分不同的订单和快速的查阅订单资料,通常都会按照一定的规则给某一个订单定一个编号,编号通常是订单中唯一的,不会有重复的现象。比如说今天是2017年03月09日,接的第8个单,就可以把此订单编号为:20170309008。
2 订单编号规范
2.1 唯一性
编号通常是订单中唯一的,不会有重复的现象。
2.2 安全性
订单编号如果是流水号的话,竞争对手就可以从订单号大概推测出你们公司的整体运营情况。所以订单编号应该是除了本公司的少数人外,其他人基本看不懂。
2.3 不能使用大规模随机码
如果订单编号全是使用随机码随机生成(例如UUID),那么这个编码本身就是一个没有意义的数据,对于我们后续的分析数据一点作用都没有。
但是采用2~3位随机码和流水号混合使用的策略,可以隐藏流水号的真实数据。
2.4 订单编号命名规则
比如:业务编码+时间戳+随机四位数+全局订单序列号
3 订单编号的生成
3.1 传统方案
订单编码的生成方案现在网上很多,主流的就是在数据库创建一个序列号表(sequence),然后在生成订单的时候,先使用一个含有事务的存储过程从sequence表获取当前订单号,然后再生成订单。但是这种方案过于复杂,而且在并发情况下,事务会影响订单的生成速度。
3.2 Redis方案
Redis命令的原子性使得我们不用考虑并发问题,可以方便的利用原子性自增操作INCR实现简单计数器功能;
//自增 public Object getIncrValue(final String key){ ValueOperations<String, String> valueOper=redisTemplate.opsForValue(); redisTemplate.setValueSerializer(new StringRedisSerializer()); Object value = valueOper.increment(key,1); return value; } //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; } |