各位大侠:
      我现在遇到一个很难解决的问题,就是我使用多个线程往数据库中的同一表插入数据,该表没有建立主键,只有一个靠程序来控制增加的序列,也就是程序运行新插一条数据,然后将序列值增加1,现在因为使用了多线程,序列值出现重复。很难解决!这几个线程插入数据是在不同的线程对象里面操作的,也就是说每一个线程操作的是不同的对象资源,而不是去操作同一对象,所以用同步方法是无法解决这个问题的,我现在项目非常着急,请问高手们有没有什么好的办法帮我一把,不胜感激!

解决方案 »

  1.   

    不用自增长字段,那就在插入的时候随即生成一个时间戳作为主键,精确到毫秒,再加一定长度的随即数,这个时间是服务器时间。这样就不会出现重复的了。如是sqlserver的话,它自身有一个生成随即字符串的东西,我搞忘了,你去查查吧
      

  2.   

    1 呈清概念,用同步方法是无法解决这个问题的
    你可以这样做
    在线程的类里面增加如下代码public static final lock = new Object();
    在需要同步的代码里用这样的方式
    synchronized(lock){
    }这样就能保证同步2 序列重复?看来只需要把你的序列做成同步就可以了!public long getNextId(){
      synchronized(MyThread.lock){
        ......
        return newId;
      } 
    }
      

  3.   

    做一个单件:
    内部存放最大序列号,然后用一个同步方法专做序列号步进的,返回步进后的序列号(这个同步方法实际上锁的是本对象,因为是单件)
    所有线程均通过这个单件得到合法序列号,如下示意代码:
    class Sequence{
        private long xlh = 0;
        private Sequence(){}
        private ststic Sequence seq = new Sequence();
        public static Sequence getInstance(){
             return seq;
        }    public synchronized long getMaxSeq(){
             xlh += 1;
             return xlh;
        }
    }
    使用:Sequence.getInstance().getMaxSeq()可以在多线程环境下获得不会重复的序列号。
      

  4.   

    如果要每次启动的时候重新从数据库得到最大序列号也可以,加在单件的构造函数里即可:
    private Sequence(){
       查询数据库获得最大序列号
       将这个最大序列号赋给xlh
    } 上面的getMaxSeq方法应该等效于:
    public   long   getMaxSeq(){ 
    synchronized(this) {
                      xlh   +=   1; 
                      return   xlh; 
            } 
    }