ITPub博客

首页 > Linux操作系统 > Linux操作系统 > oracle数据库版读者写者问题

oracle数据库版读者写者问题

原创 Linux操作系统 作者:pingley 时间:2012-04-12 10:59:31 0 删除 编辑
oracle数据库版读者写者问题
     通过读者写者的问题,可以向我们揭示oracle数据库神秘又复杂的锁机制。锁机制通过控制数据库的并发,从而保证数据的一致性与完整性。
读者:查询一个资源。写者:修改一个资源。
以下是对oracle版读者写者问题的总结:
1、一条记录只有当写者修改的时候才会被锁住。
比如update一条记录,事务会请求锁住这一行(仅仅是这一行)。这种行级锁可以最小化对数据库资源的竞争,提高更好的并发性。正常情况下不会升级行级锁到block 或者 table 级。
2、锁定了某条记录的写者会阻塞(block)并发的同样需要锁定该条记录的写者。
3、读者不会阻塞写者。
因为读者不会锁住某任何一行。除非显式的发出select ...for update 语句。该语句会锁住select 语句所读的记录。
4、写者不会阻塞读者。
当表中的某条记录因为写者的操作而改变以后。数据库使用undo 数据来提供给读者一个一致性的记录视图。虽然关于oracle 版的读者写者问题只有那么几段话,但是我个人认为这些都是精华。
oracle 把很多关于锁的机制,抽象融入了其中。下面用一个列子来揭示读者写者问题。
SQL> select sid from V$mystat where rownum = 1;
       SID
----------
        47
在session 1 中发出如下的update 语句,不提交。
SQL> update employees
  2  set salary = salary + 1000
  3  where employee_id = 100;
1 row updated.
SQL> select sid from V$mystat where rownum = 1;
       SID
----------
         1
在session 2 中发出如下的update 语句。情况是阻塞在那边,一直在等待。所以我把该语句cancel 了。
SQL> update employees
  2  set salary = salary + 1000
  3  where employee_id = 100;
^Cupdate employees
       *
ERROR at line 1:
ORA-01013: user requested cancel of current operation
再在session 2 中发出如下的update 语句,不提交。
SQL> update employees
  2  set salary = salary + 1000
  3  where employee_id = 200;
1 row updated.
从上面的示例中我们可以证明oracle版读者写者问题中的:
1、一条记录只有当写者修改的时候才会被锁住。
2、锁定了某条记录的写者会阻塞(block)并发的同样需要锁定该条记录的写者。session 1 中的update 语句锁住了employee_id=100的记录。所以阻塞了在session 2 中的同样需要锁住employee_id=100的记录的update 语句。但是session 2却可以通过执行update 语句来锁定其他他所需要锁住的记录。比如这里的employee_id=200 的那条记录。说明session 1 确实只是锁住了他所需要修改的行而不是所有的行或者整张表。
我们继续往下走。在session 1中发出如下的select 语句。
SQL> select employee_id,first_name,last_name,salary
  2  from employees
  3  where employee_id = 100;
EMPLOYEE_ID FIRST_NAME           LAST_NAME                     SALARY
----------- -------------------- ------------------------- ----------
        100 Steven               Smith                           6540
在session 2 中发出相同的select 语句。
SQL>  select employee_id,first_name,last_name,salary
  2   from employees
  3   where employee_id = 100;
EMPLOYEE_ID FIRST_NAME           LAST_NAME                     SALARY
----------- -------------------- ------------------------- ----------
        100 Steven               Smith                           5540
此时session 1 中的事务还没有提交,employee_id = 100 的记录还是被锁住了,但是却不影响读者查询,说明:写者不阻塞读者。值得注意的是读者读出来的数据。session 2中的查询结果没有反映session 1中的update...employee_id = 100 的记录的信息。因为session 1 中的update 还没有提交,锁还没有释放,修改还未生效。数据库通过使用undo data给session 2中的读者提供一个一致性的视图。
至于读者不阻塞写者我想这一点很好理解不作附加的解释。只是要来说说那个select...for update语句。先把session1 ,session 2中的修改rollback.以免影响后续的操作。
在session 1 中发出如下的select ... for update 语句。
SQL> select employee_id,first_name,last_name,salary
  2  from employees
  3  where employee_id < 110
  4  for update;
EMPLOYEE_ID FIRST_NAME           LAST_NAME                     SALARY
----------- -------------------- ------------------------- ----------
        100 Steven               Smith                           5540
        101 Neena                Kochhar                         5540
        102 Lex                  De Haan                         5540
        103 Alexander            Hunold                          5540
        104 Bruce                Ernst                           5540
        105 David                Austin                          5540
        106 Valli                Pataballa                       5540
        107 Diana                Lorentz                         5540
        108 Nancy                Greenberg                       5540
        109 Daniel               Faviet                          5540
10 rows selected.
在session 2 中发出如下的update 语句阻塞在那边,卡在那边。所以我cancel了。
SQL> update employees
  2  set salary = salary + 100
  3  where employee_id = 105;
^Cupdate employees
       *
ERROR at line 1:
ORA-01013: user requested cancel of current operation
因为select ... for update 语句相当于是写者,根据给定的条件锁住了相应的行。
我觉得如果要学习oracle 的锁机制从读者写者问题开始学习,可以先获得一个感性的认识,然后在深入oracle具体的锁机制。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26110315/viewspace-720969/,如需转载,请注明出处,否则将追究法律责任。

上一篇: oracle SQL with 子句
下一篇: oracle 数据库的锁
请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    169
  • 访问量
    715670