Chinaunix首页 | 论坛 | 博客
  • 博客访问: 586191
  • 博文数量: 772
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:02
文章分类

全部博文(772)

文章存档

2011年(1)

2008年(771)

我的朋友

分类:

2008-10-17 13:22:26

  这一篇介绍一种更高级的实现方法,这使得无论是通过过程还是直接SQL访问都可以实现读锁的机制。

  中如何实现读锁(一),上一篇文章给出了一种简单的方法,但是缺点也十分明显,就是要求用户必须采用调用函数的方式才能实现读锁。

  很多情况下,上面的条件是无法实现的,这就要求必须有一种方法对于所有的访问情况都试用。

  现在面临两个难题,一个是的读不加锁,因此必须自己实现锁的功能,二是如何将锁的实现添加到SELECT语句中,普通的触发器不会被SELECT所触发,因此通过触发器来实现这个功能是不现实的。

  对于第一个问题,可以通过Oracle的DBMS_LOCK包来实现定制用户自定义锁的实现,而第二个问题可以利用Oracle的精细访问控制来实现。

  简单描述一下思路,利用DBMS_LOCK.REQUEST过程,指定一个ID,来获取独占锁,其他会话获取同样的锁就会被锁定:


  SQL> DECLARE
  2 V_LOCK NUMBER;
  3 BEGIN
  4 V_LOCK := DBMS_LOCK.REQUEST(0, RELEASE_ON_COMMIT => TRUE);
  5 END;
  6 /

  QL 过程已成功完成。

  会话2获取同样的锁,就会被锁定:


  SQL2> DECLARE
  2 V_LOCK NUMBER;
  3 BEGIN
  4 V_LOCK := DBMS_LOCK.REQUEST(0, RELEASE_ON_COMMIT => TRUE);
  5 END;
  6 /

  SQL> COMMIT;

  提交完成。

  会话2才解锁:

   过程已成功完成。

  SQL2> COMMIT;

  提交完成。

  利用DBMS_LOCK包可以实现锁的功能,下面就是利用DBMS_RLS包添加精细访问策略,在访问目标表的时候,将锁添加到查询语句中,简单的实现如下:


  SQL> SELECT OBJECT_ID FROM USER_OBJECTS WHERE OBJECT_NAME = 'T';
  OBJECT_ID
  ----------
  93789
  SQL> CREATE OR REPLACE FUNCTION F_POLICY(OBJECT_SCHEMA IN VARCHAR2, OBJECT_NAME IN VARCHAR2)
  2 RETURN VARCHAR2 AS
  3 V_NUM NUMBER;
  4 BEGIN
  5 RETURN 'DBMS_LOCK.REQUEST(93789, 6, 60) IN (0, 4)';
  6 END;
  7 /

  函数已创建。

  SQL> EXEC DBMS_RLS.ADD_POLICY(USER, 'T', 'MYPOLICY', USER, 'F_POLICY');

 

[1]  

【责编:michael】

--------------------next---------------------

阅读(518) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~