`
littcai
  • 浏览: 248095 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

应用级自增ID的生成

 
阅读更多

背景:以前一直使用数据库的自增ID作为数据表的主键,ID的唯一性由数据库控制,在传统单机系统环境下,该方式一直是比较主流的方案。然而特定情况下,需要在插入数据前就获得记录的ID,对以该ID为基础做一些业务处理(如生成唯一业务编码),这就需要在应用层面由程序控制来生成该ID。虽然应用程序可以根据时间,机器MAC,随机数等一些因子来生成ID,或者直接使用UUID;但这些方案生成的ID长度均较大,无法兼容INT类型,由此产生了方案一。

方案一:

       在程序中定义一个INT值,记录当前使用的ID值,新对象的ID为该INT值加一。为保障多线程安全,使用轻量级AtomicInteger存储(也可使用ReentrantLock)。为了系统重启后仍然保持之前的ID,每次更新ID时同时将最新值记录到数据库,系统重启后优先从数据库中读取。

方案一改进:

       每次更新数据库性能太低,增加CACHE_SIZE属性,采用分配策略,程序中优先一次性预申请多个ID备用,只有当缓存的ID都用完后才再次向数据库申请新的ID,并更新数据库中的最新值。该方案可以满足大部分的应用需要,并且性能还不错。

 

方案一的缺点:

     无法在分布式环境下使用。由于数据锁是应用内控制的,在分布式环境下将失效,多个请求在向数据库申请新的ID时,会出现重复读的情况,申请ID的请求是不允许并发的,需要通过数据库层面的加锁才能实现请求的串行化。

 

方案一的再次改进(数据库加锁):

      以MySql为例,在申请前加写锁:LOCK TABLE TABLE_IDENTITY WRITE,将其他进程的读请求锁定,申请完后解锁:UNLOCK TABLES。后续请求读取的将是更新后的新ID。

方案一的再次改进(数据分区):

     为每个分布式节点分配一个唯一ID(如1,2,3),将ID按分布式节点数切分为多个数据块(如100,200,300),第一个节点可用ID范围为1-100,第二个节点可用范围为101-200,第三个节点可用范围为201-300。在系统规模可估的情况下,该方案可有效解决并发冲突,而且无需加锁。

 

 

 

 

 

 

分享到:
评论

相关推荐

    java快速ID自增器

    总结来说,"Java快速ID自增器"是一种解决在Java应用中生成唯一自增ID的策略。它可以是基于Java内置的原子类、数据库序列、分布式ID生成算法,或者是结合数据库和Spring框架的高级应用场景。选择哪种方案取决于具体的...

    springboot分布式自增id_javaredis_源码

    标题中的“springboot分布式自增id_javaredis_源码”表明我们关注的是一个使用Spring Boot实现的分布式系统中的自增ID生成方案,其中利用了Java Redis客户端库。在分布式环境中,确保全局唯一且顺序递增的ID是常见的...

    donkeyid, php扩展,64位自增id生成器.zip

    通过查看`donkeyid-master`目录下的源文件,我们可以学习其设计思想,了解如何在PHP中实现高性能的自增ID生成,并可能根据自己的项目需求进行调整。 此外,使用`donkeyid`扩展可以简化开发流程,避免自行编写复杂的...

    Oracle插入数据时获取自增ID

    ### Oracle插入数据时获取自增ID 在Oracle数据库中,当需要实现类似其他数据库系统(如MySQL、SQL Server等)中的自动增长字段功能时,通常会采用序列(sequence)和触发器(trigger)来实现这一需求。下面将详细...

    Go-beego框架自增id自写方法

    通过研究和学习这个项目,你可以更深入地理解如何在Go和Beego框架中自定义获取自增ID的方法,并将其应用到自己的项目中。 总的来说,解决Beego ORM在多条数据插入时无法获取自增ID的问题,需要我们编写自定义函数,...

    Oracle数据库表序列ID自增生成器

    这在多用户环境下尤其有用,确保即使在高并发环境下也能正确地自增ID,避免了ID冲突。 创建序列的基本语法如下: ```sql CREATE SEQUENCE sequence_name START WITH start_value INCREMENT BY increment_value ...

    全局自增ID设计方案

    因此,如何设计一种高效的全局自增ID生成方案成为了一个重要的技术问题。 #### 方案调研与实践 **一、数据库自增ID方案** ##### Flicker方案解析 Flicker提出的解决方案是利用MySQL自身的auto_increment特性来...

    SAP自定义自增ID序号及调用代码

    下面是一个示例代码段,展示了如何通过调用SAP内置函数模块来实现自增ID的生成: ```abap DATA: p_id TYPE zaccid. DATA: p_code TYPE c. PERFORM frm_get_init_log_id USING p_id p_code. IF p_code IS INITIAL....

    SQLserver中按年月日生成日期型自增编码.pdf

    SQL Server 中按年月日生成日期型自增编码 本文档介绍了在 SQL Server 中生成日期型自增编码的方法,通过创建两个函数 `GenCustomCode` 和 `GenCustomID`,可以生成按年月日的日期型自增编码。该方法可以应用于各种...

    Twitter的分布式自增ID雪花算法snowflake

    雪花算法是Twitter开源的一种分布式ID生成算法,它能够生成全局唯一、递增且无碰撞的64位整数ID。这个算法在分布式系统中非常适用,因为传统的序列号生成方式在分布式环境中往往难以解决冲突问题。下面我们将详细...

    获取自增ID.docx

    对于很多应用来说,使用自增ID是一种简单且高效的实现方式。自增ID指的是在表中自动递增的字段值,通常用于主键。本文档将详细介绍如何在Java环境下通过不同方法获取数据库中的自增ID。 #### 二、获取自增ID的方法 ...

    cpp-idgen是一个可以生成全局唯一自增id的分布式的高可用服务

    cpp-idgen是一个专门为生成全局唯一且自增ID...总之,cpp-idgen作为一款分布式ID生成服务,为大型分布式系统提供了可靠的全局唯一自增ID解决方案,其设计理念和技术实现对于理解和构建类似的系统具有重要的参考价值。

    php 根据自增id创建唯一编号类

    - 示例中,创建了一个`IDCode`实例,并用一系列自增id生成对应的编号,用以演示编号生成的过程。 - 例如,自增id为1的编号将被格式化为`F-A-001`,其中`F`是自定义的前缀,`A`是通过id计算得出的字母,`001`是填充...

    全局唯一ID生成

    在单体应用时代,我们可以通过数据库自增ID或时间戳+序列号等方式生成唯一ID。但在分布式环境下,这些方法往往无法满足需求,因为它们可能会导致ID冲突或性能瓶颈。 一种常见的分布式ID生成方案是雪花算法...

    一个用于自动生成更方便阅读的id的mongoose插件

    描述中提到,插件生成的ID形如'1610211329190',这种设计结合了时间和自增数字。前10位是时间戳,以毫秒为单位,这使得ID能够反映创建时间的顺序。后面的3位是一个自增数字,确保在同一毫秒内创建的多个文档也能拥有...

    Hibernate教程02_ID生成策略

    本教程将详细讲解Hibernate中的ID生成策略,以及如何在实际项目中灵活应用。 首先,ID生成策略是Hibernate为了保证每个实体对象在数据库中的唯一性而设计的一种机制。它定义了如何生成和分配给新创建的对象一个唯一...

    细聊分布式ID生成方法.pdf

    针对不同的应用场景,本文介绍了几种常见的分布式ID生成方案。 ##### 3.1 消息ID(Message-ID) 对于消息传递系统而言,确保消息ID的全局唯一性至关重要。一种常见做法是基于时间戳进行排序,并限制每批次生成的...

    Java实现Twitter的分布式自增ID算法snowflake

    总结来说,Java实现的Twitter Snowflake算法是一种高效、有序的分布式自增ID生成器,适用于需要全局唯一标识且对时间顺序有要求的系统。通过合理的位分配,它能够在分布式环境中提供线性扩展性和时间上的顺序性。

Global site tag (gtag.js) - Google Analytics