Oracle plsql 避免等待被锁资源的方法

FOR UPDATE NOWAIT语句:有的时候我们打开一个游标是为了更新或者删除一些记录,这种情况下我们希望 在打开游标的时候即锁定相关记录,应该使用for update nowait语句,倘若锁定失败我们就停止不再继续,以免 出现长时间等待资源的死锁情况。或者仅仅想想修改某一个记录,在update前,也可以select  ....where  .....  for update nowait  一下 锁定要修改的记录。

SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT];

举例1: 

DECLARE
CURSOR sal_cursor IS
SELECT e.department_id, employee_id, last_name, salary
FROM employees e, departments d
WHERE d.department_id = e.department_id
 and d.department_id = 60
FOR UPDATE OF salary NOWAIT;
BEGIN
FOR emp_record IN sal_cursor
LOOP
 IF emp_record.salary < 5000 THEN
 UPDATE employees
SET salary = emp_record.salary * 1.10
WHERE CURRENT OF sal_cursor;
 END IF;
END LOOP;
END;

举例2:

PROCEDURE upd_sal(p_job_id     VARCHAR,
                    p_min_salary NUMBER,
                    p_max_salary NUMBER) IS
    e_salary EXCEPTION;
    v_job_id VARCHAR2(32);
    e_resource_busy EXCEPTION;
    PRAGMA EXCEPTION_INIT(e_resource_busy,
                          -54);
  BEGIN
  
    IF p_max_salary < p_min_salary THEN
      RAISE e_salary;
    END IF;
    SELECT jobs.job_id
      INTO v_job_id
      FROM jobs
     WHERE jobs.job_id = p_job_id
       FOR UPDATE OF min_salary NOWAIT; --这里上锁
    
    UPDATE jobs
       SET jobs.min_salary = p_min_salary,
           jobs.max_salary = p_max_salary
     WHERE jobs.job_id = p_job_id;
  EXCEPTION
    WHEN e_salary THEN
      dbms_output.put_line('max_salary < min_salary');
      raise_application_error(-20001,
                              'max_salary < min_salary');
    WHEN no_data_found THEN
      dbms_output.put_line('no this job id');
      raise_application_error(-20001,
                              'no this job id');
    WHEN e_resource_busy THEN   --表记录被锁时也可以捕获
      raise_application_error(-20001,
                              '表记录被锁');
      /*WHEN OTHERS THEN
      dbms_output.put_line('表被锁');*/
  
  END;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值