zoukankan      html  css  js  c++  java
  • 测试oracle10g 的IO隔离级别serializable

    用sys用户给scott一个默认表空间
    create tablespace lisx datafile '+DATA' ;
    alter user scott default tablespace lisx ;

    建测试表
    create table dept
    (deptno number(9),
    deptname varchar2(20),
    detail   varchar2(50)
    );
    insert into dept values(1,'业扩','新装增容') ;
    insert into dept values(2,'账务','账务') ;
    insert into dept values(3,'电费','电费') ;
    insert into dept values(4,'质量','测试DBA打包') ;

    commit ;

    打开两个scott的会话
    在会话1里面:
    SQL> col deptname format a10 ;
    SQL> col detail format a20 ;
    SQL> select * from dept ;

        DEPTNO DEPTNAME   DETAIL
    ---------- ---------- --------------------
             1 业扩        新装增容
             2 账务         账务
             3 电费        电费
             4 质量        测试DBA打包

    SQL> show user       
    USER is "SCOTT"
    SQL>
    SQL>
    SQL> update dept set detail='账务2222' where deptno=2 ;

    1 row updated.

    然后在会话2里:
    SQL> set sqlprom 'SQL2>' ;
    SQL2>
    SQL2>col deptname format a10 ;
    SQL2>col detail format a20 ;
    SQL2>select * from dept ;

        DEPTNO DEPTNAME   DETAIL
    ---------- ---------- --------------------
             1 业扩        新装增容
             2 账务         账务
             3 电费        电费
             4 质量        测试DBA打包

    SQL2>update dept set detail='账务33333' where deptno=2 ; 

    如果第一个会话不提交,那么SQL2的修改会失败,一直等待前一个会话释放资源,形成了语句的死锁。

    如果会话一提交,那么会话2也可以成功执行,但是因为修改的标准是参照最初的值,所以会覆盖会话1的修改结果。我们称之为不可重复读(Non Repeatable Read)
    SQL>commit ;

    Commit complete.

    SQL2>commit ;

    Commit complete.

    下面在第二个会话设置
    SQL2>alter session set isolation_level=serializable ;
    我们看看设置IO隔离级别后的效果,主要是看看能否避免丢失修改。

    SQL2>select * from dept ;

        DEPTNO DEPTNAME   DETAIL
    ---------- ---------- --------------------
             1 业扩        新装增容
             2 账务         账务33333
             3 电费        电费
             4 质量        测试DBA打包

    在会话1里设置IO隔离级别
    SQL>alter session set isolation_level=serializable ;

    Session altered.

    SQL> update dept set detail='44444' where deptno=2 ;

    1 row updated.

    先不提交,在会话2里面执行
    SQL2>update dept set detail='55555' where deptno=2 ;
    该修改会处于等待状态
     
    然后提交会话1
    SQL> commit ;

    Commit complete.

    会话2里面报错了:
    SQL2>update dept set detail='55555' where deptno=2 ;
    update dept set detail='55555' where deptno=2
           *
    ERROR at line 1:
    ORA-08177: can't serialize access for this transaction

    因此通过设置会话1的隔离级别isolation_level=serializable,避免了其他会话的修改丢失。
    理论上serializable还能避免幻影读,但是幻影读不太好实现。
    SQL标准中定义了4中IO隔离级别
    READ Uncommited
    READ Commited  避免了脏读
    Repeatable     避免了脏读,不可重复读
    Serializable   避免了脏读,不可重复读,幻影读

    但是ORACLE只有3中:
    READ Commited
    Serializable
    Read Only

    对于READ Uncommited,oracle无法模拟。
    对于Repeatable,ORACLE可以通过悲观锁和乐观锁实现Repeatable
    Read Only和Serializable的区别是对于丢失修改,前者是禁止修改,后者报错:
    ORA-08177: can't serialize access for this transaction

  • 相关阅读:
    新手学Python必看的几个练手小项目,轻松不枯燥哦!
    实力讲解,一文读懂Python闭包与装饰器!
    Python必不可少的小技巧,一行代码减少一半内存占用!
    千篇一律的Python爬虫,大神精心总结的爬虫套路!
    Python小技巧:获取Linux系统基本信息
    大数据时代|搭建Python数据分析平台
    利用Python实时接收微博小姐姐动态啦~
    Python爬虫:把爬取到的数据插入到execl中
    正则表达式 元字符
    正则表达式——(2) – 语法
  • 原文地址:https://www.cnblogs.com/caibird2005/p/1691768.html
Copyright © 2011-2022 走看看