登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

梦想之鹰的天空

天高任鸟飞......放飞....心情..........放飞.....梦想

 
 
 

日志

 
 

在Oracle中如何实现读锁(一)  

2008-06-09 09:30:11|  分类: 数据库 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Oracle中根本没有读锁,楼主的要求和Oracle尽可能提高并发的目的是截然相反的。

  写这篇文章的目的并不是说这个需求有什么普遍性,而是为了说明在Oracle中其实没有什么是做不到的,即使这个需求和Oracle的设计本意相违背,另外希望这篇文章中的一些思路能起到抛砖引玉的作用。

  楼主提出的问题是“怎么样让一个表,一个时间只能一个人读”,简单概括一下就是建立起读锁的机制。而且这个读锁还不能是共享锁,而必须是有个独占锁。

  考虑到Oracle中根本不存在读锁,那么必须将思路进行转化。

  最先想到的是,将查询转化为DML,这样就可以获取到锁,避免其他用户对改对象同时进行访问。

  最简单的实现方式莫过于建立一个存储过程,在存储过程中首先LOCK TABLE,然后进行查询,将查询的结果返回。

  简单实现如下:

  SQL> CREATE TABLE T

  2 (

  3 ID NUMBER PRIMARY KEY,

  4 NAME VARCHAR2(30)

  5 );

  表已创建。

  SQL> INSERT INTO T SELECT ROWNUM, TNAME FROM TAB;

  已创建23行。

  SQL> COMMIT;

  提交完成。

  下面构建函数:

SQL> CREATE OR REPLACE FUNCTION F_QUERY_T RETURN SYS_REFCURSOR AS
  2 V_CURSOR SYS_REFCURSOR;
  3 BEGIN
  4 LOCK TABLE T IN EXCLUSIVE MODE;
  5 OPEN V_CURSOR FOR 'SELECT * FROM T';
  6 RETURN V_CURSOR;
  7 END;
  8 /

  函数已创建。


  SQL> SELECT F_QUERY_T FROM DUAL;
  F_QUERY_T
  --------------------
  CURSOR STATEMENT : 1
  CURSOR STATEMENT : 1
  ID NAME
  ---------- ------------------------------
  1 CHAINED_ROWS
  2 DEPT
  3 EMP
  4 BONUS
  5 SALGRADE
  6 DUMMY
  7 T_PK
  8 S_T
  9 MV_CAPABILITIES_TABLE
  10 TB_OBJECT_1136
  11 MLOG$_TB_OBJECT_1136
  12 RUPD$_TB_OBJECT_1136
  13 MV_TB_OBJECT_1136
  14 ORD_ORDER
  15 TT
  16 MV_T
  17 T_PRIMARY
  18 T_UPDATE
  19 T
  20 INF_PRODUCT
  21 INF_DRUG
  22 T_OLD
  23 INF_PRODUCT_PROPERTY

  已选择23行。

  下面在另外一个会话登陆,仍然通过函数来访问:


  SQL> SET SQLP 'SQL2> '
  SQL2> SELECT F_QUERY_T FROM DUAL;

  会话被锁定,只有会话1提交或回滚,会话2才能继续查询:

  SQL> COMMIT;

  提交完成。

  这时会话2解锁:


  F_QUERY_T
  --------------------
  CURSOR STATEMENT : 1
  CURSOR STATEMENT : 1
  ID NAME
  ---------- ------------------------------
  1 CHAINED_ROWS
  2 DEPT
  3 EMP
  4 BONUS
  5 SALGRADE
  6 DUMMY
  7 T_PK
  8 S_T
  9 MV_CAPABILITIES_TABLE
  10 TB_OBJECT_1136
  11 MLOG$_TB_OBJECT_1136
  12 RUPD$_TB_OBJECT_1136
  13 MV_TB_OBJECT_1136
  14 ORD_ORDER
  15 TT
  16 MV_T
  17 T_PRIMARY
  18 T_UPDATE
  19 T
  20 INF_PRODUCT
  21 INF_DRUG
  22 T_OLD
  23 INF_PRODUCT_PROPERTY

  已选择23行。

 SQL2> ROLLBACK;

  回退已完成。

  通过这种方法,简单的实现了读锁的功能,不过这种方法的缺点也很明显,要求用户必须通过函数的方式访问,而直接通过SQL方式访问是可以绕过锁机制的。

  评论这张
 
阅读(375)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018