Oracle存储过程中使用行锁的示例

  以前对Oracle锁只概念上的一点点了解,没有认真考虑或使用过。直到在开发过程中遇到了由于没有使用锁而导致的并发问题,才对此重视起来。
  举个例子来说明我遇到的问题。
  一个入库单表(T_RKD),每一条记录对应着一条入库信息,还有个一对多的关联表来记录此入库单的明细信息。我使用T_RKD表中一个字段来标识这条记录是否入过库,若未入过,对明细进行入库处理。入过之后,修改入库标志。以上操作通过一个存储过程来完成。
  以上操作,当两个人同时处理一条入库记录的时候,两个人同时取入库标志,看到的都是未入过库,然后,你可以想到了,入库操作就被做了两次。
  并发操作的时候,如果考虑不周,会出现很多难以发现的错误。这时就可以用到锁了。我使用一个行锁来解决这个问题,通过锁,使该存储过程不能同时由多个线程调用,处理同一条记录。
  存储过程的大致代码如下:
create or replace procedure P1(pdm in varchar2) is
v_flagrk char(1);
begin
  select flagrk into v_flagrk from t_rkd where dm=pdm for update wait 5;
  --开始事务
  --执行业务逻辑
  --修改入库标志
  --提交事务
 --若出异常,回滚
end P1;
/

  在存储过程开始执行的时候,先申请独占锁,这样就可以避免由于并发导致的业务逻辑被多次执行的问题。
  /***********本人原创,欢迎转载,转载请保留本人信息*************/
  作者:wallimn 电邮:[email protected] 时间:2009-10-17
  博客:http://wallimn.iteye.com
  网络硬盘:http://wallimn.ys168.com
  /***********文章发表请与本人联系,作者保留所有权利*************/

  以上为在存储过程中锁住一条记录,比较容易想到,其实还有一种情况,是要同时锁住多条记录,如库存数据。如何来解决呢,我翻了几遍PL/SQL程序设计,加上一点灵感,才想到解决方案,很简单,贴出来希望对朋友们有帮助,使用下面的代码就可以了:
create or replace procedure P2(pdm in varchar2) is
   type kcdm_table_type is table of T_KC.dm%TYPE index by binary_integer;
   kcdm_table			 kcdm_table_type;
begin
  select dm bulk collect into kcdm_table from T_KC 
     where  ...
     for update wait 7;
  --开始事务
  --执行业务逻辑
  --提交事务
 --若出异常,回滚
end P2;
/

  就是使用bulk collect,执行一个批量操作。

  以上我是首次研究使用锁的一点想法,欢迎大家留言与我讨论。

你可能感兴趣的:(多线程,oracle,sql)