2009年2月8日星期日

事务

事务是由一个或多个SQL语句组成的逻辑操作单位(logical unit of work)。事务具有原子性(atomic)。一个事务内所有SQL语句对数据库产生的影响,要么全部被提交(commit)(作用到数据库中),要么全部回滚(roll back)(将对数据库的修改撤销)。
一个事务开始于用户提交第一条可执行(executable)的SQL语句,结束于之后进行的提交(commit)或回滚操作。使用COMMIT或ROLLBACK语句能够显式地(explicitly)结束事务,而提交一个DDL语句可以隐式地(implicitly)结束事务。
如果发生问题,导致事务中的一条或两条SQL语句不能执行,那么整个事务必须回滚,这样才能保证完整性。
1、语句的执行与事务控制(statement execution and transaction control)
一个成功执行的SQL语句与一个提交的事务是有区别的。一个SQL语句成功执行表明此语句:解析正常、是有效的SQL语法结构、作为一个独立的语句运行无误(例如:在一个多行更新(multirow update)操作中所有数据行都被成功修改)。
但是包含此语句的事务被提交之前,整个事务都可以被回滚,事务内所有语句对数据库的修改都可以被撤销。尽管发生了回滚,事务内的SQL语句却是成功执行的。
提交(commit)意味着用户显示地(explicitly)或隐式地(implicitly)要求将事务中对数据的修改永久地记录到数据库当中。当用户执行COMMIT语句时即为显式的提高叫操作,当数据库应用程序正常结束或一个数据定义语句(data definition language)成功执行后将发生隐式的提交操作。事务被提交后,事务内SQL语句的对数据的修改将被永久地记录到数据库中,其他用户将能够看到这些改变。在事务提交后执行的查询就能看到变化后的数据了。
用户可以在开始一个事务时,使用SET TRANSACTION ... NAME语句为此事务命名。这有助于用户监控长时间运行的事务,以及处理不可信的分布式事务(in-doubt distributed transaction)。
2、语句级回滚statement-level rollback
如果在一个SQL语句在执行过程中发生了错误,那么此语句对数据库产生的影响都将被回滚。回滚后就如同此语句从未执行过,这种操作被称为语句级回滚。
在语句执行过程中,任何发生的错误都将会导致语句级回滚,例如同一个表中插入数据造成主键(primary key)值重复即为此类错误。一个造成死锁(deadlock)(访问相同数据而产生的竞争)的SQL语句也会导致语句级回滚。而在SQL语句解析(parsing)的过程中发生的错误(例如语法错误),因为此语句还没有执行,所以不会产生语句级回滚。
一个SQL语句执行失败只会使此语句所做的数据修改无效,而不会导致当前事务中此语句之前的语句所做的数据修改无效。如果执行失败的是DDL语句那么此语句之前隐式执行提交操作不会被撤销。
3、可恢复的空间分配问题
当一个持续时间较长的数据库操作在执行过程中遭遇空间分配失败时,oracle可以将此操作暂时性挂起(suspend),并在空间分配问题解决后恢复(resume)其执行。当发生空间分配问题时,oracle数据库不会立即 给执行此操作的用户返回错误提示,而是等待管理员解决此问题。当空间分配问题被纠正后,挂起的操作就可以自动地恢复执行。
注:只有在客户端使用ALTER SESSION语句的语法显式地将会话设定为可恢复(resumable)后,SQL语句才能运行在可恢复模式下(resumable mode)。
当满足以下条件时,运行于可恢复的空间分配模式下的语句将被挂起(suspend):无可用空间、达到最大的数据扩展(maximum extent)限制、超出空间配额(space quota)限制
在不可恢复的空间分配模式下,以上条件将导致运行错误,并使SQL语句回滚。
当语句被挂起将导致所在事务同时被挂起。事务所使用的所有资源在语句挂起期间都将被保留。
当产生错误的条件消除后(例如,管理员进行了处理,或其他查询使用的排序空间(sort space)被释放),被挂起的语句将自动地恢复执行。

没有评论:

发表评论