oracle事务简述

一、事务的概念

事务会把数据库从一种一致状态转变为另一种一致状态,这就是事务的任务。

oracle的事务提供了ACID特征:

原子性(atomicity):事务中的所有动作要么都发生,要么都不发生。

一致性(consistency):事务将数据库从一种一致状态转变为下一种一致状态。

隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。

持久性(durability):事务一旦提交,其结果就是永久性的。

其中最重要的特性是它的原子性。

二、事务控制语句

一定要显式地使用commit或rollback来终止你的事务。

commit:要想使用这个语句的最简形式,只需发出commit。也可以更详细一些,写为commit work,不过这二者是等价的。commit会结束你的事务,并使得已做的所有修改成为永久性的(持久保存)。commit语句还有一些扩展用于分布式事务中。利用这些扩展,允许增加一些有意义的注释为commit加标签(对事务加标签),以及强调提交一个可疑的分布式事务。

rollback:要想使用这个语句的最简形式,只需发出rollback。同样地,你也可以罗嗦一些,写为rollback work,但是二者是等价的。回滚会结束你的事务,并撤销正在进行的所有未提交的修改。为此要读取存储在回滚段/undo段中的信息,并把数据库块恢复到事务开始之前的状态(后面我将把回滚段/undo段统称为undo段,Oracle 10g中都喜欢用这个词)。

savepoint:savepoint允许你在事务中创建一个“标记点”(marked point),一个事务中可以有多个savepoint。

rollback to :这个语句与savepoint命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。所以,可以发出两条update语句,后面跟一个savepoint,然后又是两条delete语句。如果执行delete语句期间出现了某种异常情况,而且你捕获到这个异常,并发出rollback to savepoint命令,事务就会回滚到指定的savepoint,撤销delete完成的所有工作,而update语句完成的工作不受影响。

set transaction:这条语句允许你设置不同的事务属性,如事务的隔离级别以及事务是只读的还是可读写的。使用手动undo管理时,还可以使用这个来指示事务使用某个特定的undo段,不过不推荐这种做法。

最常用的控制语句就是commit和rollback。savepoint语句的用途有点特殊。oracle在内部频繁地使用了这个语句,你会发现这语句在你的应用中可能也有用。

三、原子性

事务的性质中最重要的就是原子性。

1、语句级原子性

一个语句要么完全成功,要么完全不成功,如果语句有触发器,触发器也会回滚。

2、过程级原子性

oracle把pl/sql代码块认为是语句,如果在存储过程中使用

exception
when others then
错误处理

就不会回滚已经成功的语句,异常定义是为了让存储过程能够执行成功。

如果没有定义exception就会回滚存储过程中的所有语句。

为了保证过程的原子性,不应该捕获when others。

3、事务的原子性

最后,还有一种事务级原子性的概念。事务(也就是一组SQL语句作为一个工作单元一同执行)的总目标是把数据库从一种一致状态转变为另一种一致状态。

为了实现这个目标,事务也是原子性的,事务完成的所有工作要么完全提交并成为永久性的,要么会回滚并撤销。像语句一样,事务是一个原子性的工作单元。提交一个事务后,接收到数据库返回的“成功”信息后,你就能知道事务完成的所有工作都已经成为永久性的。

如果在一个事务中,使用rollback,那么这个事务执行的sql语句、存储过程的结果都会回滚。

四、完整性约束和事务

完整性约束是在什么时候检查的?

完整性约束会在整个sql语句得到处理之后立即检查。即在sql语句执行时候检查,如果违反了完整性约束sql语句会回滚。

五、事务的提交

在oracle中,每个事务都应该只在必要时才提交,而在此之前不能提交。事务的大小要根据需要而定。锁、阻塞等问题并不是决定事务大小的关键,数据完整性才是确定事务大小的根本。

锁不是稀有资源,并发的数据读取器和数据写入器之间不存在竞争问题。这样在数据库中就能有健壮的事务。这些事务不必很短,而要根据需求有足够长的持续时间(但是不能不必要地太长)。

事务不是为了方便计算机及其软件,而是为了保护你的数据。

1、在循环中提交事务

建议事务提交不要过于频繁,按业务过程的要求以适当的频度提交,并且相应地设置undo段大小。