PLSQL中select for update cursor

简介:

开始

复制代码
DECLARE
  CURSOR emp_cursor IS
    SELECT empno, ename, dname
    FROM emp, dept
    WHERE  emp.deptno=dept.deptno
    AND  emp.deptno = 20
    FOR UPDATE OF sal NOWAIT;

  emp_record emp_cursor%ROWTYPE;

BEGIN
   
LOOP

  IF NOT emp_cursor%ISOPEN  THEN
     OPEN emp_cursor;
  END IF; 
  
  FETCH emp_cursor INTO  emp_record; 
  EXIT WHEN emp_cursor%NOTFOUND;
  
  dbms_output.put_line
     ('empno is:' || emp_record.empno || '-- emp name is:' || emp_record.ename ||'-- dept is:' || emp_record.dname);

END LOOP;

IF emp_cursor%ISOPEN  THEN
     dbms_output.put_line('Now to close cursor!');
     CLOSE emp_cursor;
END IF; 

END;
复制代码

当没有其他session 干扰的时候,会有如下的结果:

复制代码
anonymous block completed
empno is:7369-- emp name is:SMITH-- dept is:RESEARCH
empno is:7566-- emp name is:JONES-- dept is:RESEARCH
empno is:7788-- emp name is:SCOTT-- dept is:RESEARCH
empno is:7876-- emp name is:ADAMS-- dept is:RESEARCH
empno is:7902-- emp name is:FORD-- dept is:RESEARCH
Now to close cursor!
复制代码

如果有另外一个session 拿住某些记录(这里是 auto commit off状态,所以是为提交。也就是 在一个隐含的事务里面):

SQL> update emp set ename='XFORD' where deptno=20;

5 rows updated.

SQL> 

然后 保持这种状态,重新来执行,结果是:

复制代码
Error report:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
ORA-06512: at line 3
ORA-06512: at line 16
00054. 00000 -  "resource busy and acquire with NOWAIT specified"
*Cause:    Resource interested is busy.
*Action:   Retry if necessary.
复制代码

如果我们不是用 NOWAIT关键字,会如何?

复制代码
DECLARE
  CURSOR emp_cursor IS
    SELECT empno, ename, dname
    FROM emp, dept
    WHERE  emp.deptno=dept.deptno
    AND  emp.deptno = 20
    FOR UPDATE OF sal;

  emp_record emp_cursor%ROWTYPE;

BEGIN
   
LOOP

  IF NOT emp_cursor%ISOPEN  THEN
     OPEN emp_cursor;
  END IF; 
  
  FETCH emp_cursor INTO  emp_record; 
  EXIT WHEN emp_cursor%NOTFOUND;
  
  dbms_output.put_line
     ('empno is:' || emp_record.empno || '-- emp name is:' || emp_record.ename ||'-- dept is:' || emp_record.dname);

END LOOP;

IF emp_cursor%ISOPEN  THEN
     dbms_output.put_line('Now to close cursor!');
     CLOSE emp_cursor;
END IF; 

END;
复制代码

这个时候再执行,就会一直等待,等待对方释放资源。

结束





本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/11/14/2770274.html,如需转载请自行联系原作者

目录
相关文章
|
5月前
|
SQL 存储 关系型数据库
SQL的基本语法以及SQL语句的关键字的使用,SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP等。
SQL的基本语法以及SQL语句的关键字的使用,SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP等。
|
4月前
|
SQL 数据库
SQL INSERT INTO SELECT 语句
SQL INSERT INTO SELECT 语句
62 3
|
SQL 数据库
INSERT DESC UPDATE SELECT
INSERT DESC UPDATE SELECT
92 0
Unsafe query: ‘Update‘ statement without ‘where‘ updates all table rows at once
Unsafe query: ‘Update‘ statement without ‘where‘ updates all table rows at once
664 0
|
SQL 关系型数据库 MySQL
Select for update使用详解
前言 近期开发与钱相关的项目,在高并发场景下对数据的准确行有很高的要求,用到了for update,故总结一波以便日后留恋。 for update的使用场景 如果遇到存在高并发并且对于数据的准确性很有要求的场景,是需要了解和使用for update的。 比如涉及到金钱、库存等。一般这些操作都是很长一串并且是开启事务的。如果库存刚开始读的时候是1,而立马另一个进程进行了update将库存更新为0了,而事务还没有结束,会将错的数据一直执行下去,就会有问题。所以需要for upate 进行数据加锁防止高并发时候数据出错。
2306 0