zoukankan      html  css  js  c++  java
  • ORACLE HANDBOOK系列之七:事务(Transaction)

    1概述

     

    (在一个会话中)事务何时开始:当数据库遇到第一个DMLUPDATE/INSERT/DELETE/MERGE语句。 

    (在一个会话中)事务何时结束:结束于第一个COMMIT/ROLLBACK/DDL/GRANT/REVOKE。对于DLL/GRANT/REVOKE,这些命令的内部嵌套了一个COMMIT语句。

    上面的两句话是基本教义,就好比88耻之于和谐社会一样重要。

     

    2事务级与语句级

    CREATE TABLE t_trans_sample(fnum NUMBER(3));

     

    insert into t_trans_sample values(1);       --sql-1
    insert into t_trans_sample values(2);       --sql-2

    根据教义,sql-1sql-2属于同一事务,此时如果我们执行commit/rollback,两条语句将同时被提交/回滚,即‘事务级’提交/回滚。

    如果是这样呢:

     

    insert into t_trans_sample values(1);       --sql-1
    insert into t_trans_sample values(‘a’);    --sql-2

    sql-2出错,此时只有出错的语句被回滚(当然受该语句影响的可能是多行数据),sql-1仍然处于未提交状态,即语句级回滚。

    总结一下:用户显式执行的提交/回滚,通常总是‘事务级’的;当语句出错时由Oracle自动执行的回滚,通常总是‘语句级’的。

     

    3隐式保存点

     

    insert into t_trans_sample values(1);              --sql-1
    begin
    insert into t_trans_sample values(2);           --sql-2
    insert into t_trans_sample values(‘a’);       --sql-3
    end;

    此时的结果是sql-2也被自动回滚了,只剩下sql-1的结果处于未提交状态。为什么,不是说应该是语句级的么?这是因为,执行PL/SQL匿名块、或者调用存储过程,会在紧挨着调用之前插入一个隐式的savepoint,当块内部出错并自动回滚时,并非是语句级的,而是回滚到此savepoint为止


    但是,如果语句块中有
    exception处理模块:

     

    insert into t_trans_sample values(1);              --sql-1
    begin
    insert into t_trans_sample values(2);           --sql-2
    insert into t_trans_sample values(‘a’);       --sql-3
    exception
       
    when others then
        
    null;
    end;

    此时只有sql-3被回滚,sql-1sql-2仍处于未提交状态。


    还有一点需要注意,
    savepoint只针对回滚的情况,对于提交操作无影响,下面示例中的commit会将三条结果都提交:

     

    insert into t_trans_sample values(1);              --sql-1
    begin
    insert into t_trans_sample values(2);           --sql-2
    insert into t_trans_sample values(3);           --sql-3
    commit;
    end;

     

    4触发器与事务

    触发器代码中不允许发出任何事务控制语句,触发器与触发该触发器的SQL语句同属于一个事务,它只能随着外部事务的提交/回滚而提交/回滚。如果触发器内的DML(如果有的话)出错,则此DML被回滚,同时引发此触发器的DML也将被回滚。

    (但在oracle8i 以及更高的版本中,你可以创建作为自治事务而执行的触发器,在这种情况下,触发器可以做提交或回滚操作,而与触发该触发器的外部SQL所在的事务无关,自治事务见后文)

     

    5 Db link与事务

    Oracle可以透明地处理分布式事务,意思就是,即便一个事务中涉及的表可能位于不同的oracle server上(通过Db link进行访问),对事务本身没有任何影响。这里就不作示例测试了。

     

    6自治事务

    普通的事务是无法进行嵌套的,例如你有一个大事务涉及10DML,你想先commit中间的3条是无法实现的。自治事务的出现很好地解决了这个问题,它可以使嵌套中的事务保持各自的独立,对比下面两个例子:

    1

     

    insert into t_trans_sample values(1);
    begin
         
    insert into t_trans_sample values(2);
         
    commit;
    end;
    /

    2

     

    insert into t_trans_sample values(1);
    declare
         pragma autonomous_transaction;
    begin
         
    insert into t_trans_sample values(2);
         
    commit;
    end;
    /

    1)中两条语句都被提交,这在前面的文章里已经提过了,(2)中只有第二个insert语句被提交,第一个仍然处于未提交的状态,可以看到自治事务的效果。在实际应用中,自治事务常常用于记录错误日志,通常来说,记录错误日志的事务应该独立出来,不应该与主事务杂揉在一起,这种情况下就应该使用自治事务了。

     

  • 相关阅读:
    setTimeout,clearTimeout,setInterval,clearInteral详解
    关于JS读取DOM对象(标签)的自定义属性
    jquery.form.js官方插件介绍Form插件,支持Ajax,支持Ajax文件上传
    按回车键切换input鼠标光标
    电压跟随器的作用,以及其中两个电阻的作用?
    阅读RB521S30肖特基二极管的datasheet
    配置linux内核,解决lcd logo和十分钟息屏!
    配置linux,关闭LCD的console控制台输出。
    记录一次编译linux内核或者说编译dtbs的问题!!
    copy_from_user的详细用法!
  • 原文地址:https://www.cnblogs.com/morvenhuang/p/2075492.html
Copyright © 2011-2022 走看看