Oracle DB处理数据(五)
FOR UPDATE
ORDER BY employee_id;
仅当发出ROLLBACK或COMMIT语句时才释放锁。
如果SELECT语句要锁定另一个用户已锁定的某一行,数据库就会一直等待到该行可用为止,然后返回SELECT语句的结果。
SELECT语句中的FOR UPDATE子句
当你针对数据库发出SELECT语句来查询某些记录时并不会锁定所选行。通常情况下这样做是有必要的,因为默认情况下任何指定时间锁定的记录数量保持在绝对最低水平:也就是只锁定那些已更改但尚未提交的记录。只有那样,其他用户才能够读取更改前的记录(数据的“前像”)。但是,有时需要在程序中对某组记录进行更改之前将其锁定。
使用Oracle 提供的SELECT语句的FOR UPDATE子句即可执行该锁定。
发出SELECT...FOR UPDATE语句时,关系数据库管理系统(RDBMS) 会自动获得对由SELECT语句标识的所有行的行级互斥锁,因此可暂挂这些记录“仅供你进行更改”。
其他人将无法更改这些记录,直至你执行ROLLBACK或COMMIT语句为止。你可以将可选的关键字NOWAIT附加到FOR UPDATE子句中,告知Oracle Server 在另一
用户锁定该表时不要等待。在这种情况下,可以立即将控制权返回给你的程序或SQL Developer 环境,以便你可以执行其它工作或者仅仅等待一段时间后重试。如果没有NOWAIT子句,则会暂时终止你的进程,直至其他用户通过发出COMMIT或ROLLBACK命名释放锁而使该表可用为止。
FOR UPDATE子句:示例
可以针对多个表在SELECT语句中使用FOR UPDATE子句。
SELECT e.employee_id, e.salary, e.commission_pct FROM employees e JOIN departments d USING (department_id) WHERE job_id = 'ST_CLERK' AND location_id = 1500
FOR UPDATE
ORDER BY e.employee_id;
已锁定EMPLOYEES和DEPARTMENTS表中的所有行。
使用FOR UPDATE OF column_name来限定要更改的列,此时只会锁定特定表中的行。
在示例中,该语句锁定了EMPLOYEES表中JOB_ID设置为ST_CLERK且LOCATION_ID设置为1500 的那些行,同时还锁定了DEPARTMENTS表中LOCATION_ID的部门设置为1500 的那些行。
你可使用FOR UPDATE OF column_name来限定要更改的列。FOR UPDATE子句中的OF列表并没有限制你只更改选定行的那些列。所有行仍处于锁定状态;如果仅仅在查询中列出了FOR UPDATE子句而在OF关键字后没有添加任何列,那么,数据库将会锁定FROM子句列出的所有表中的所有指定行。
以下语句只锁定了EMPLOYEES表中ST_CLERK位于LOCATION_ID1500 的那些行,而没有锁定DEPARTMENTS表中的任何行:
SELECT e.employee_id, e.salary, e.commission_pct FROM employees e JOIN departments d USING (department_id) WHERE job_id = 'ST_CLERK' AND location_id = 1500
FOR UPDATE OF e.salary
ORDER BY e.employee_id;
在以下示例中,数据库得知要等待五秒钟该行才可用,因而此时会将控制权返回给用户。
SELECT employee_id, salary, commission_pct, job_id FROM employees WHERE job_id = 'SA_REP'
FOR UPDATE WAIT 5
ORDER BY employee_id;
小结