我在一个web应用中利用程序来产生唯一编号。但是是从数据库中编号由程序自动增加来产生编号。
例如数据库中数据原来为:
  id 
=========
  1
  2
  3
=========
现在由程序自动产生应该是4,但是如果有两个以上用户同时要求产生编号,这时就会产生多个唯一编号
为4。我要如何才能实现多个用户之间的同步啊?

解决方案 »

  1.   

    把产生序号的代码放到一个静态同步方法中
    public synchronized static int getSerialNo(){
            i++;
            return i;
        }
      

  2.   

    主键生成还是不要自己控制吧,与业务逻辑无关最好
    找个主键生成的包,推荐用uuid
      

  3.   

    如果要自己生成的话,同步就可以了。像 flyoversky(碧海) 那样就OK
      

  4.   

    要不,每次先取一下MAX(id),然后+1
      

  5.   

    但是有个用户申请了个id然后正在保存,但是还没有保存到数据库。就在这个时候又有个用户也申请id这时他申请的id就会和前一用户申请的id是相同的。
      

  6.   

    public synchronized static int getSerialNo(){
        取数据库中MAX_ID;
        newID = MAX_ID+1;
        更新数据库,MAX_ID = newID;
        返回newID;
    }
      

  7.   

    但是有个用户在getSerialNo()后有个其他用户也来执行getSerialNo()那么他们的id是不是一样啊。
      

  8.   

    唯一编号要数据库生成比较好,它里面本身就有同步机制,不需要你在程序实现
    如果你用的是oracle,那可以用SEQUENCE
      

  9.   

    System.currentTimeMillis() 
    试试这个吧,毫秒级的唯一编号,不过不能顺序编,只能是唯一的~
      

  10.   

    序列好可以用guid生成,有生之年不太可能重复吧
      

  11.   

    用笨点的方法.
    select 然后update 再insert
      

  12.   

    使用静态变量来控制最好吧private static int uid;这样,不管你new多少个对象。uid++都是在第一个你生成的对象的基础上+1的。
      

  13.   

    如果是当个jvm应用 使用单例
    如果是多个jvm应用 使用网络单例
      

  14.   

    如果不考虑顺序用uuid
    如果需要有顺序可以用sequence
      

  15.   

    一种方式:使用数据库提供的自增长功能,如果你的数据最终是进入数据库的,则采用这种方式比较好。各种数据库都提供了此功能,唯实现有所不同,大体上有直接字段支持(典型的如mysql),identity声明(如m$sql、db2等)、sequence(如oracle)等几种。
    此方式的缺点是,a.依赖数据库,b.在数据备份复制时要特别注意,c.很难跨多个数据库,d.一般不能跨表。
    二种方式:使用程序产生。又有几种方式,一种就是简单的序列号增长,一种是使用uuid,再一种是用户自定义的特殊格式(譬如多数业务部门都有特别的产品序列号的规格说明)。实现上可用singleton等模式。个人建议使用Apache的jakarta项目中的commons项目中的Id子项目 http://jakarta.apache.org/commons/sandbox/id/ ,包括了绝大多数id产生方式。显然你自己写出来的不太可能比专家写的更好。个人建议,如果是业务主键(可能会暴露给外界的),应采用第二种方式,如果仅仅是系统内部的相互引用所需的key,特别是仅仅作为数据库内部设施而不会暴露给数据层以上的情况,采用第一种方式。
      

  16.   

    但是有个用户在getSerialNo()后有个其他用户也来执行getSerialNo()那么他们的id是不是一样啊。
    ------------------------------------------
    public synchronized static int getSerialNo(){
        取数据库中MAX_ID;
        newID = MAX_ID+1;
        更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
        返回newID;
    }
      

  17.   

    数据库发号如果是Oracle可以考虑采用Sequence
      

  18.   

    但是有个用户在getSerialNo()后有个其他用户也来执行getSerialNo()那么他们的id是不是一样啊。
    ------------------------------------------
    public synchronized static int getSerialNo(){
        取数据库中MAX_ID;
        newID = MAX_ID+1;
        更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
        返回newID;
    }
      

  19.   

    TO kefon(天天维她命):
    System.currentTimeMillis()???你用一个for循环把System.currentTimeMillis()打出来,看看多少个重复的,算算CPU主频,就知道1毫秒相当于多少个CPU时钟周期了.并发时不出问题才怪.
      

  20.   

    在oracle里建个序列,然后用序列名.nextval就行
      

  21.   

    上面有许多方法很好,支持这个:
    public synchronized static int getSerialNo(){
        取数据库中MAX_ID;
        newID = MAX_ID+1;
        更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
        返回newID;
    }不过也可以用触发器,因为编号最终是要写入数据库的,before insert的时候,搞个触发器,产生编号,应该万无一失啊
      

  22.   

    首先感谢大家的帮忙. 
    我现在是这样来实现的:利用spring来管理bean并在保存数据库的方法中产生id.
    这样可以吗?
      

  23.   

    jdk1.5好像有UUID了吧~楼主可以看下~
      

  24.   

    public synchronized static int getSerialNo(){
        取数据库中MAX_ID;
        newID = MAX_ID+1;
        更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
        返回newID;
    }支持这个方法,因为我就是用这个方法
      

  25.   

    取数据库中MAX_ID;
        newID = MAX_ID+1;
    这样的方法,如果有多次的删除操作,这个流水号会变的很大,呵呵,就是不好看
      

  26.   

    我想要像这种的,很长的.而且没有规律
    serialVersionUID = 3513826563487354618L
      

  27.   

    用GUID,全球唯一标志符,由128位字符组成.具体方法网上多的是.
      

  28.   

    同步就可以了synchronized保证程序进行的唯一性