Oracle 事务

       事务(Transaction)是数据库区别于文件系统的特性之一。 在文件系统中,如果你正把文件写到一半,操作系统突然崩溃了,这个文件就很可能会被破坏。而数据库则不同,事务会把数据库从一种一致状态转变为另一种一致状态。这就是事务的任务。在数据库中提交工作时,可以确保要么所有修改都已经保存,要么所有修改都不保存。另外,还能保证实现了保护数据完整性的各种规则和检查。

      事务的四个特性ACID相信大家都很熟悉:

原子性(atomicity):事务中的所有动作要么都发生,要么都不发生。
一致性(consistency):事务将数据库从一种一致状态转变为下一种一致状态。
隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。
持久性(durability):事务一旦提交,其结果就是永久性的。

 

1.事务控制语句

       Oracle中不需要专门的语句来“开始事务”。隐含地,事务会在修改数据的第一条语句处开始(也就是得到TX锁的第一条语句)。也可以使用SET TRANSACTION或DBMS_TRANSACTION包来显示地开始一个事务,但是这一步并不是必要的,这与其他的许多数据库不同,因为那些数据库中都必须显式地开始事务。如果发出COMMIT或ROLLBACK语句,就会显式地结束一个事务。

        COMMIT:要想使用这个语句的最简形式,只需发出COMMIT。也可以更详细一些,写为COMMIT WORK,不过这二者是等价的。
        ROLLBACK:要想使用这个语句的最简形式,只需发出ROLLBACK。同样地,你也可以罗嗦一些,写为ROLLBACK WORK,但是二者是等价的。
        SAVEPOINT:SAVEPOINT允许你在事务中创建一个“标记点”(marked point),一个事务中可以有多个SAVEPOINT。
        ROLLBACK TO <SAVEPOINT>:这个语句与SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。所以,可以发出两条UPDATE语句,后面跟一个SAVEPOINT,然后又是两条DELETE语句。如果执行DELETE语句期间出现了某种异常情况,而且你捕获到这个异常,并发出ROLLBACK TO SAVEPOINT命令,事务就会回滚到指定的SAVEPOINT,撤销DELETE完成的所有工作,而UPDATE语句完成的工作不受影响。
        SET TRANSACTION:这条语句允许你设置不同的事务属性,如事务的隔离级别以及事务是只读的还是可读写的。使用手动undo管理时,还可以使用这个 来指示事务使用某个特定的undo段。

 

2.原子性

         Oracle在语句原子性方面与其他数据库不同的地方在于Oracle悄悄地在每个数据库调用外面包了一个SAVEPOINT。例如对于触发器,Sybase或SQL Server数据库的情况恰恰相反。这些系统中的触发器会独立于触发语句执行。如果触发器遇到一个错误,它必须显式 地回滚自己的工作,然后产生另外一个错误来回滚触发语句。否则,即使触发语句(或该语句的另外某个部分)最终会失败,触发器完成的工作也会持久保留。

          还有一点是Oracle把PL/SQL匿名块也当作语句。也就是说在一个PL/SQL里如果运行期间有错误,那么其所有做的工作全部撤消。但是如果提交的时候用exception语句,例如:

          begin

          p;

          exception

          when others then null;

          end;

          /

          在此,我们运行的代码块会忽略所有错误。如果代码中包含一个WHEN OTHERS异常处理器,但其中没有一个RAISE来重新引发异常,我认为这样的代码都是有bug的。它会悄悄地忽略错误,这就改变了事务的语义。如果捕获WHEN OTHERS,并把异常转换为旧式的返回码,这会改变数据库本该有的表现。

          一种好的写法是:

          begin
          savepoint sp;
          p;
          exception
          when others then
          rollback to sp;
          end;
          /

         最后,还有一种事务级原子性的概念。事务(也就是一组SQL语句作为一个工作单元一同执行)的总目标是把数据库从一种一致状态转变为另一种一致状态。
为了实现这个目标,事务也是原子性的,事务完成的所有工作要么完全提交并成为永久性的,要么会回滚并撤销。像语句一样,事务是一个原子性的工作单元。提交一个事务后,接收到数据库返回的“成功”信息后,你就能知道事务完成的所有工作都已经成为永久性的。

 

3.完整性约束和事务

       需要指出到底什么时候检查完整性约束。默认情况下,完整性约束会在整个SQL语句得到处理之后才进行检查。也有一些可延迟的约束允许将完整性约束的验证延迟到应用请求时(发出一个SET CONSTRAINTS ALL IMMEDIATE命令)才完成,或者延迟到发出COMMIT时再检查

  

  3.1 IMMEDIATE约束

       在这种情况下,完整性约束会在整个SQL语句得到处理之后立即检查。注意,这里我用的是“SQL语句”而不只是“语句”。如果一个PL/SQL存储过程中有多条SQL语句,那么在每条SQL语句执行之后都会立即验证其完整性约束,而不是在这个存储过程完成后才检查它。

 

  3.2 DEFERRABLE约束和级联更新

        从Oracle8.0开始,我们还能够延迟约束检查,对于许多操作来说,这很有好处。首先能想到的是,可能需要将一个主键的UPDATE级联到子键。也许很多人会说:这没有必要,因为主键是不可变的(我就是这些人之一),但是还有人坚持要有级联UPDATE。有了可延迟的约束,就使得级联更新成为可能。只要把约束设为deferrable就可。

 

4. 自治事务

      自治事务(autonomous transaction)允许你创建一个“事务中的事务),它能独立于其父事务提交或回滚。利用自治事务,可以挂起当前执行的事务,开始一个新事务,完成一些工作,然后提交或回滚,所有这些都不影响当前执行事务的状态。

      例如以下建立语句:

       create table t ( msg varchar2(25) );

 

       create or replace procedure Autonomous_Insert

       as

       pragma autonomous_transaction;   #设为自治事务

       begin

       insert into t values ( 'Autonomous Insert' );

       commit;

       end;

       /

       使用上面的自治匿名块,执行以下语句,有:

       begin

       insert into t values ( 'Anonymous Block' );

       Autonomous_Insert;

       rollback;

       end;

       /

      

       参看t表的结果为:

       select * from t;

       MSG
       -------------------------
       Autonomous Insert

       可以看到的结果是尽管Autonomous_Insert中有commit语句,后面的rollback还是会把Anonymous Block给rollback,如果使用非自治事务匿名块,而块中有commit语句,则会把Anonymous Block给提交了,后面的rollback并不能产生任何作用。

       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值