如题线程安全问题 在存储过程里面如何实现 从一个表取数据,保证在存储过程这一级 就 实现 望高手赐教 目前知道用序列 

解决方案 »

  1.   

    其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全
      

  2.   

    其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理  看来论坛高手都藏起来了额
      

  3.   

    其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理  看来论坛高手都藏起来了额就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101  第三个就是102 等等 ,需要在 数据库用存储过程实现 
    怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作
      

  4.   

    其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理  看来论坛高手都藏起来了额就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101  第三个就是102 等等 ,需要在 数据库用存储过程实现 
    怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作不是这个意思了 是多用户同时访问,这种等待的 肯定不行, 必须处理一下。我的目的并不是插入,而是 取得  保证取得的 时候 都是唯一但是取前肯定插入了 ,目前存在现成问题是在解决这个现成问题
      

  5.   

    序列就可以啊,你插入的时候获取插入的序列sql语句 insert  表名(id,其他列)  values(序列.nextval ,其他列值) returning id into 存储过程变量
      

  6.   

    可以采用比较笨的方法,在操作表前先锁住 比如FORUPDATE,取出当前值,+1后在commit
    另外,如果是JAVA的话,可以在该方法前加上关键字synchronized。
      

  7.   

    提供一个,仅供参考!
    /**
     * 取最后四位数,同时更新,出现断号正常
     * @return
     * @throws Exception
     */
    public synchronized String getLastNumber()throws Exception{
    Connection conn = null;
    String num ="";
    try{
    conn = this.getConnection();
    conn.setAutoCommit(false);
    num = numberDao.getLastNumber(conn);
    numberDao.updateLastNumber(conn, num);
    conn.commit();
    }catch(Exception e){
    conn.rollback();
    e.printStackTrace();
    throw new Exception(e.getMessage());
    }finally{
    if(conn!=null){
    conn.close();
    }
    }
    return num;
    }
      

  8.   

    使用seq 真能保证挨个有序么?
    SELECT SEQ.NEXTVAL,SEQ.CURRENTVAL FROM DUAL;看看结果呢
      

  9.   

    lz思路有点乱,如果只是查询时就给最大值加1,可以试试包变量的方式,以下是我写的简单例子。如果查询出来没有用时还还把号还回去,就需要写比较复杂的逻辑了,可以通过包变量或在java等程序代码中实现判断后,在向数据库写入时控制去重复。
    SQL> 
    SQL> create table test(a number);
     
    Table created
    SQL> insert into test values (101);
     
    1 row inserted
    SQL> insert into test values (102);
     
    1 row inserted
    SQL> insert into test values (103);
     
    1 row inserted
    SQL> insert into test values (104);
     
    1 row inserted
     
    SQL> commit;
     
    Commit complete
     
    SQL> 
    SQL> create or replace package testp is
      2    seqNo number := 0;
      3    strNoHead varchar2(8000) := '';
      4    function getNext(sourceNo number) return varchar2;
      5  end testp;
      6  /
     
    Package created
    SQL> create or replace package body testp is
      2    function getNext(sourceNo number) return varchar2 is
      3    strRet varchar2(8000);
      4    begin
      5      strNoHead := 'xxx';
      6      if (sourceNo >= seqNo) then
      7        seqNo := sourceNo;
      8      end if;
      9      seqNo := seqNo + 1;
     10      strRet := strNoHead || to_char(seqNo);
     11      return strRet;
     12    end;
     13  end testp;
     14  /
     
    Package body created
     
    SQL> select testp.getNext(max(a)) from test;
     
    TESTP.GETNEXT(MAX(A))
    --------------------------------------------------------------------------------
    xxx105
     
    SQL> select testp.getNext(max(a)) from test;
     
    TESTP.GETNEXT(MAX(A))
    --------------------------------------------------------------------------------
    xxx106
     
    SQL> select testp.getNext(max(a)) from test;
     
    TESTP.GETNEXT(MAX(A))
    --------------------------------------------------------------------------------
    xxx107
     
    SQL> 
      

  10.   

    抱歉,这个不行,忘记测试了,不能突破session
      

  11.   

    现在我用 锁表的方式 实现了 。 不过又有一个新问题 ,  我把 数据库名 当参数 传递进来 ,然后 用  立即执行 ,然后总出异常ls_tmp_sql := 'select nvl(max(to_number(substr('||ls_fsjkzdm||','||ls_sub_num||'))),1) from '||ls_fsjkmc||'.'||ls_fsjkbm||' where '||ls_fsjkzdm||' like '||'''%'||ls_tmp_pre||'______%'||''';';
      
                   
                   --execute immediate ls_tmp_sql into lh_tmp1;求高人看看 我这个 写的 对不对此外 into写到 select 值的 后面也是不对  总 异常
      

  12.   

    like '||'''%'||ls_tmp_pre||'______%'||''';';--此处在语句内部不需要“;”号了,改为
    like '||'''%'||ls_tmp_pre||'______%'||'''';