事务的控制语句

事务是使数据库和文件系统分离的一个特性。在文件系统中,如果在写一个文件时,操作系统崩溃,文件就可能被破坏。确实有“日志”的文件系统,能把文件恢复到以前某一时间的状态。然而,如果保持两个文件同步,它就无能为力了,如果更新了一个文件,在完成第二个文件更新之前系统出现故障,这两个文件将不会同步。

       这就是在数据库的在在事务的主要目的。事务能够把数据库从一个一致的状态转移支另一个状态。这就是事务的作用。当在数据库中提交工作时,就能确定要么存储了所有的修改,要么什么都没有存储。进一步说,能保证各种实施数据完整性的规则和检查得以实现。

        数据库事务应展示由ACID描述的属性。ACID是以下单词的首字母缩写:

<1>原子性:一个事务要么完全发生,要么完全不发生。

<2>一致性:事务把数据库从一个一致的状态转变到另一个状态。

<3>隔离性:在事务提交以前,其他事务察觉不到事务的影响。

<4>持久性:一量事务提交,它是永久的。

 

在oracle中没有“开始事务”语句。事务隐式地开始于第一条修改数据的语句(第一钉得到tx锁定的语句)。发出一条COMMIT或ROLLBACK语句显式地结束事务。

       在oracle中,事务是原子的,要么全部提交包含在事务中的所有语句(永久的),要么所有语句回滚。这种保护

也扩展到单条语句。一条语句要么完全成功执行,要么完全回滚。注意,这里所说提语句回滚。一条语句的失败不能使它前面执行的语句自动圆润。它们的荛是保存的,要么提交要么回滚。

       在详细讨论语句和事务的“原子性”的含义之前,先来了解可以使用的各种事务控制语句。它们是

<1>COMMIT----用最简单形式,可以只写COMMIT。也可以详细地写成COMMIT WORK,两者是等效的。COMMIT结束事务,使改变成永久的。在分布式事务中,对COMMIT语句有扩充。这些扩充允许使用一些有意义注释 标记COMMIT(标记事务),并且强制提交有异议的分布式事务。

<2>ROLLBACK----用最简单的形式,可以只定ROLLBACK。同样,也可以详细地写成ROLLBACK WORK,两者是等效的。回滚结束事务,撤消任何没有提交 的操作。这是通过读取存储在回滚段里的信息来实现的,并把数据库块恢复到开始执行事务之前的状态。

<3>SAVEPOINT---SAVEPOINt允许在事务中创建一个“标记点”。在单个事务中可以有多个SAVEPOINT.

<4>ROLBAKC TO <SAVEPOIN>----本命令和上面的SAVEPOINT命令一起使用。可以回滚事务到标记点,而不回滚标记点前边的工作。因此,可以使用两条UPDATE语句,后边跟一个SAVEPOINT,然后是两条DELETE语句。如果执行DELETE语句时发生错误,或遇到一些例外情况,事务将回滚到SAVEPOINT命名的地方,撤消DELETE,但不撤消UPDATE语句。

<5>set transaction----本语句允许设置不同的事务属性,例如隔离级和是否只读或可读写。也可以使用此语句来指示事务使用某个特定的回滚段。

      这就是全部事务控制语句,没有其他的了。最常控制语句是COMMIT和ROLLBACK。使用SAVEPOINT语句有一些特殊作用,在内部,oracle使用它最频繁,也能在应用程序中找到使用它的地方。

       现在对事务控制语句进行了粗略的介绍,以下介绍语句和事务原子性的含义。考虑如下语句:

insert into t values (1);

很明显,如果上面语句由于违反约束性而失败,将不能插入行。然而,考虑下例,在表T中插入或删除来激发一个触发器,该触发器适当 地优化表T2中的cnt列:

sql>create table t2(cnt int);

sql>insert into t2  values(0);

sql>create table t (x int check(x>0));

sql>create triger t_triger

       before insert or delete on t for each row

       begin

               if(inserting) then

                         update t2 set cnt = cnt +1;

               else

                         update t2 set cnt = cnt - 1;

                end if;

                dbms_output.put_line('I fired and updated' || sql%rowcount || 'rows');

end;

     在这种情况下不清楚会发生什么情况,如果触发器激发以后发生错误,触发器能不能发挥作用呢?也就是说,如果触发器激发并且更新了t2,但是在表t中没有插入行,会造成什么结果?结果很清楚,就是我们不希望看到的,在t中没有实际插入行,而在t2中增加cnt列的值。幸运的是,在oracle中来自客户端原始语句insert into t,在这种情况下,要么完全成功,要么完全失败。该语句是原子性的(不可分的)。

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值