WEB开发网
开发学院数据库Oracle 在Oracle中如何实现读锁(一) 阅读

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

 2008-05-31 12:41:36 来源:WEB开发网   
核心提示:虽然不清楚楼主的具体目的是什么,但是楼主提出的问题确实有点意思,在Oracle中如何实现读锁(一),因为Oracle中根本没有读锁,楼主的要求和Oracle尽可能提高并发的目的是截然相反的,不过这种方法的缺点也很明显,要求用户必须通过函数的方式访问,写这篇文章的目的并不是说这个需求有什么普遍性,而是为了说明在Oracl

虽然不清楚楼主的具体目的是什么,但是楼主提出的问题确实有点意思。因为Oracle中根本没有读锁,楼主的要求和Oracle尽可能提高并发的目的是截然相反的。

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

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

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

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

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

简单实现如下:

  SQL>CREATETABLET
  2(
  3IDNUMBERPRIMARYKEY,
  4NAMEVARCHAR2(30)
  5);

表已创建。

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

已创建23行。

SQL> COMMIT;

提交完成。

下面构建函数:

SQL>CREATEORREPLACEFUNCTIONF_QUERY_TRETURNSYS_REFCURSORAS

2V_CURSORSYS_REFCURSOR;

3BEGIN

4LOCKTABLETINEXCLUSIVEMODE;

5OPENV_CURSORFOR'SELECT*FROMT';

6RETURNV_CURSOR;

7END;

8/

函数已创建。

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

已选择23行。

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

  SQL>SETSQLP'SQL2>'
  SQL2>SELECTF_QUERY_TFROMDUAL;

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

SQL> COMMIT;

提交完成。

这时会话2解锁:

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

已选择23行。

SQL2> ROLLBACK;

回退已完成。

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

Tags:Oracle 如何 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接