基于DB的全局唯一id
来源:互联网 发布:php生成8位唯一邀请码 编辑:程序博客网 时间:2024/05/18 01:43
基于DB的全局唯一id
同一个jvm内使用atomicLong保证,非同一个jvm内使用db的乐观锁保证。
当id超过设置的最大值后,自动归零复位。
格式为yymmdd+ 业务码 + id
代码如下
/** * 内部id生成器 * Created by carey on 2017/5/26. */@Componentpublic class InnerIdemIdGen { private Map<InnerBusinessEnum, IdGenerator> bizGenCache = new HashMap<>(); private Logger logger = LoggerFactory.getLogger("biz"); /** * id步长控制 */ private final long StepSize = 200; /** * 最大的步长,10?的格式 */ private final long MaxCount = 1000000; @Resource private IdGenMapper idGenMapper; /** * 初始化,从db加载 */ @PostConstruct private void init() { for (InnerBusinessEnum innerBusinessEnum : InnerBusinessEnum.values()) { IdGenerator idGenerator = new IdGenerator(innerBusinessEnum.getName()); idGenerator.init(); bizGenCache.put(innerBusinessEnum, idGenerator); } logger.info("主键生成器注册完成"); } /** * 生成全局幂等id * yymmdd + bizcode(3位) + 6位id * @param innerBusinessEnum 内部定义的业务线 * @return */ public long gen(InnerBusinessEnum innerBusinessEnum) { IdGenerator idGenerator = bizGenCache.get(innerBusinessEnum); SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); String time = sdf.format(new Date()).concat(innerBusinessEnum.getCode()); return Long.valueOf(time) * MaxCount + idGenerator.next(); } /** * 生成器 * 同jvm内使用atomic保证 * 非jvm内使用乐观锁保证 */ private class IdGenerator { /** * 表中的名字 */ private String key; private AtomicLong count = new AtomicLong(); /** * 下一次的天花板 需要重新从db中获取 */ private volatile long nextGenTop; IdGenerator(String key) { this.key = key; } /** * 使用乐观锁 */ private void init() { int changeSize; long curCount; do { curCount = idGenMapper.getIndex(key); changeSize = idGenMapper.updateIndex(key, curCount, StepSize); } while (changeSize != 1); count.set(curCount); nextGenTop = curCount + StepSize; } /** * 获取下一个id * @return */ private long next() { long curCount = count.incrementAndGet(); if (curCount <= nextGenTop) { return curCount; } synchronized (count) { curCount = count.incrementAndGet(); if (curCount < nextGenTop) { return curCount; } init(); curCount = count.incrementAndGet(); if (curCount > MaxCount) { reset(nextGenTop); return count.incrementAndGet(); } return curCount; } } /** * id达到了上限, 复位 * @param topCount */ private void reset(long topCount) { int changeSize = idGenMapper.reset(key, topCount); if (0 == changeSize) { init(); } else { nextGenTop = StepSize; count.set(0); } } } public enum InnerBusinessEnum { PICC_ID("picc", "001"), Test("test", "002"); /** * 表中的名字 */ private String name; /** * 业务标识码 * yymmdd + bizCode + id */ private String code; private InnerBusinessEnum(String name, String code) { this.name = name; this.code = code; } public String getName() { return name; } public String getCode() { return code; } }}
db的部分
<select id="getIndex" resultType="java.lang.Long"> select cur_count from cop_id_gen where biz_key = '${key}'; </select> <update id="updateIndex"> update cop_id_gen set cur_count = cur_count + ${stepSize} WHERE biz_key = '${key}' and cur_count = ${cur_count}; </update> <update id="reset"> update cop_id_gen set cur_count = 0 WHERE biz_key = '${key}' and cur_count = ${cur_count}; </update>
阅读全文
0 0
- 基于DB的全局唯一id
- 生成全局唯一的ID,java 中
- 全局唯一ID的生成方式
- 全局唯一ID的生成策略对比
- 基于业务对Twitter生成全局唯一ID的SnowFlake算法的改造
- 基于 Redis 的全局唯一性ID生成器的一些实现思路
- 生成全局唯一Id
- 全局唯一ID生成器
- DRDS生成全局唯一ID
- 全局唯一ID生成方案
- Mysql实现全局唯一ID
- flickr 对于分布式系统生成全局唯一ID的解决方案
- MongoDB文档(Document)全局唯一ID的设计思路
- MongoDB文档全局唯一ID的设计思路
- MongoDB文档(Document)全局唯一ID的设计思路
- 业务系统需要怎样的全局唯一ID
- 业务系统需要怎样的全局唯一ID
- flickr的分表全局唯一id实现方式
- Linux下MySQL数据库常用基本操作
- Windriver生成cpci驱动程序知识点简单讲解
- Integer,int,String相互转换
- Struts2框架自学之路——拦截器
- 解决VS2015安装后stdio.h ucrtd.lib等文件无法识别问题,即include+lib环境变量配置
- 基于DB的全局唯一id
- 表达式
- 算法实战:根据Key或Value对Map进行排序及其应用
- Activity的传值的几种方式
- java生成验证码
- 如何在地图上打点数百万条数据
- 【算法题】链表冒泡排序
- mr中的combiner
- 内存监视