说明:tcount 表中有两个字段x记录是流水号,item是类型思路:根据不同的item取相应的流水号,流水号是递增的--取流水号,如何解决并发?
procedure getX(p_item varchar2,cu out number)
  is
  p number;
  begin
    p:=0;
    cu:=1;
    select count(*) into p from tcount where item=p_item;
    if p>0 then
       begin
         select x+1 into cu from tcount where item=p_item;
         update tcount set x=x+1 where item=p_item;
       end;
     else
       begin
              insert into tcount values(1,p_item);
       end;
    end if;
    
    commit;    
  end;

解决方案 »

  1.   

    不用自己实现这部分
    看下oracle sequence
      

  2.   

    项目因为其他原因,不能使用sequence,不然也就简单了。
      

  3.   

    你的代码稍微改一下
    1.加上自治事务。
    2.对表tcount使用for update行锁定
      

  4.   

    兄台,有空能否帮着把代码改下?我觉得用for update也是有问题的。
      

  5.   

    可以用for update,每次修改表前必须获得for update成功才能修改,缺点就是无法并发,只能大家排队一个个来.使用sequence才是最合理的方案,为什么不能用sequence呢?
      

  6.   

    如果允许跳号,那么sequence是最佳的选择
      

  7.   

    涉及到新旧系统,以及多台服务器备份(在备份时,sequence有些问题,所以DBA明示不允许使用sequence,至于DBA采用什么备份方式,这点我不清楚,呵呵~~)。
      

  8.   

    to LZ:流水号有实际业务含义吗? 还是仅仅是作为主键标识用的?
    如果无意义,则可以使用sys_guid()来生成无意义的、不重复的值。Insert into customer (id_cust, cust_name) values ( sys_guid() ,’Jimmy’);
    注意: 如果要使用主键ID值作为条件查询,必须使用hextoraw函数才会用到主键索引。例如: WHERE ID=hextoraw('A36072E794E35537E04400144F674217') ; 否则不会使用主键索引,带来性能问题。
      

  9.   

    使用随机的主键,会让数据库记录变得无法控制。看得出,LZ是有意要获得递增序列的,这或许也是需求之一。
    另外,利用for update不会引起并发问题啊。因为锁定是针对某个item的所有数据,因此,不会存在并发问题。对于同一个item的多事务串行是必需的。另外,可能需要注意,LZ取记录数目的做法并不可取,想象用户删除数据的情况下。肯定会出现重号。
      

  10.   

    递增序列确实是需求之一,而且这张tcount序列表是不会删除的。
    用for update是,对item已存在的类型来说,是可以解决,
    但如果最初tcount为空时,是有插入动作的,如果这里并发,如何处理呢?
    代码如下:
    ...
    else
      begin
          insert into tcount values(1,p_item);
      end;
    end if;
        
    commit;   
    end;
      

  11.   

    参考了5楼的思路。
    把代码贴出来,欢迎拍砖。
    相信取流水号对许多项目是有帮助.--取顺序流水号
    procedure getX(p_item varchar2,cu out number)
      is  begin    cu:=0;   
        autonomous_insert(p_item);
        
        select x+1 into cu from tcount where item=p_item for update;
        update tcount set x=x+1 where item=p_item;
        commit;
        
      end;
      
      
      procedure autonomous_insert(p_item varchar2)
        is 
        --使用自治事务
        pragma autonomous_transaction;
        begin
          insert into tcount 
            select 0,p_item
            from tcount
            where  not exists(select 1 from tcount t where t.item=p_item) 
            and rownum=1;        commit;
            exception when others then 
              rollback;
         end;
    end aa;
      

  12.   

    更改:
     procedure autonomous_insert(p_item varchar2)
      is  
      --使用自治事务
      pragma autonomous_transaction;
      begin
      insert into tcount  
      select 0,p_item
      from dual where not exists(select 1 from tcount t where t.item=p_item);  commit;
      exception when others then  
      rollback;
      end;
      

  13.   


    利用这个方法啊,那不是每次去拿序列号的时候,都会尝试向表中插入数据?
    会影响效率的吧。LZ是利用唯一性约束item来保证?