前言
通常情況下我們在系統中創建訂單編號時,都會按照一定的規則去生成,因為訂單編號是唯一的,不能重復的。
命名規則
例:業務編碼+時間戳+流水號
方案
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; }