你可以在select时加上for update。
如:
select max(id)
into iMaxId
from ta_mytable
where name='大牛'
for update;
。。(一些操作)
update ta_mytable
set id=iMaxId+1
where name='大牛'

解决方案 »

  1.   

    你的这个Procedure在多用户访问下肯定会出现锁的现象,
    如果你的ID不是要求严格+1生成的,你可以考虑用Oracle的序列,即Sequence来生成ID
      

  2.   

    这么说来,Oracle的存储过程会自动串行化执行的吗???
      

  3.   

    如果是多用户环境,当然有问题的了
    存取过程在同一个时间,允许多个用户同时调用。
    那么在你的select 与 update之间,只要有别的用户执行了这个过程,问题就来了。
    具体你可以做实验!
    语句可以通过如下方式改造
    1、锁定
    select max(id)
    into iMaxId
    from ta_mytable
    where name='大牛'
    for update nowait;
    2、事务一致性(序列读)
    set transaction isolation level serializable;
    建议采用第一种方法。
    并可以在过程中加入如下语句
    excaption
       when others then
         --写日志
    end;
    这样的话,通过日志,你就可以知道并行情况下,发生争用的可能(也就是不加for update时可能出错的情况)
      

  4.   

    如果是多用户环境,当然有问题的了
    存取过程在同一个时间,允许多个用户同时调用。
    那么在你的select 与 update之间,只要有别的用户执行了这个过程,问题就来了。
    具体你可以做实验!
    语句可以通过如下方式改造
    1、锁定
    select max(id)
    into iMaxId
    from ta_mytable
    where name='大牛'
    for update nowait;
    2、事务一致性(序列读)
    set transaction isolation level serializable;
    建议采用第一种方法。
    并可以在过程中加入如下语句
    excaption
       when others then
         --写日志
    end;
    这样的话,通过日志,你就可以知道并行情况下,发生争用的可能(也就是不加for update时可能出错的情况)非常同意以上观点因此一定要加for update!