冯东的博客

每天学一点,不断进取
  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

Oracle锁定选出的结果集

Posted on 2008-09-08 14:52  冯东  阅读(477)  评论(0编辑  收藏  举报
    经常会遇到这样的情况,用SQL读取一些数据,然后根据数据进行一些处理。比如学生的学号是依次递增的,通常会用下面的方法来取得并生成一个学号
select max(sno) as sno from students;
程序取得sno然后插入
insert into students values(sno+1,...);
这种方法平时可能没有问题,但是存在这样一种情况A、B两个用户几乎同一时间操作,A先执行了select max(sno) 操作,在A取得最大学号但没有完成插入或者提骄傲操作时B也执行了select max(sno) 操作,此时A、B取到的 sno是一样的。但是这种情况是不允许出现的,怎样避免这种情况呢?
对选中的行上锁!
针对上面的sql语句需要小的改动
select sno from students sno=(select max(sno) from students) fro update;
这时Oracle将会锁定选中的行,如果没有commit活rollback操作的话,在他后面执行的语句将会陷入等待状态。这样就可以解决类似上面的问题了。A先执行了select max(sno) 操作,在A取得最大学号但没有完成插入或者提骄傲操作时B也执行了select max(sno) 操作,因为这一行被加上了串行锁,所以B用户只好等待,等A用户执行了commit操作,B用户才有返回结果,这样一来就避免了取得同一个值的问题。