oracle-事务oracle-transaction信息管理与信息系统学士学位论文.doc
《oracle-事务oracle-transaction信息管理与信息系统学士学位论文.doc》由会员分享,可在线阅读,更多相关《oracle-事务oracle-transaction信息管理与信息系统学士学位论文.doc(27页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、xx工业大学xxx学院本科毕业设计(论文)ORACLE 事务ORACLE TRANSACTION 系 部 管理学部 专 业 信息管理与信息系统 年 级 2011 级 班级名称 11信管 1班 学 号 15041101031 学生姓名 xxx 指导教师 xxx 2015 年 5 月目 录1 ORACLE 事务12 ORACLE TRANSACTION111 ORACLE 事务 事务(Transaction)是数据库区别于文件系统的特性之一。在文件系统中,如果你正把文件写 到一半,操作系统突然崩溃了,这个文件就很可能会被破坏。不错,确实还有一些“日报式”(journaled)之类的文件系统,它们能
2、把文件恢复到某个时间点。不过,如果需要保证两个文件同步,这些文件系统就无能为力了,倘若你更新了一个文件,在更新完第二个文件之前,系统突然失败了,就会有两个不同步的文件。这正是数据库中引入事务的主要目的,事务会把数据库从一种一致状态转变为另一种一致状态。这就是事务的任务。在数据库中提交工作时,可以确保要么所有修改都已经保存,要么所有修改都不保存。另外,还能保证实现了保护数据完整性的各种规则和检查。在上一章中,我们从并发控制角度讨论了事务,并说明了在高度并发的数据访问条件下,根据Oracle的多版本控制读一致模型,Oracle事务每次如何提供一致的数据。Oracle中的事务体现了所有必要的ACID
3、特征。ACID是以下4个词的缩写。原子性(atomicity ):事务中的所有动作要么都发生,要么都不发生。一致性(consistency):事务将数据库从一种一致状态转变为下一种一致状态。隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。持久性(durability):事务一旦提交,其结果就是永久性的。这里讨论原子性的含义,以及Oracle中原子性对语句有什么影响。首先会介绍COMMIT,SAVEPOINT和ROLLBACK等事务控制语句,并讨论事务中如何保证完整性约束。我们会谈到,如果你原来一直在其他数据库中开发,可能在事务方面养成一些坏习惯(即后面所说的“不好
4、的事务习惯”)。这里还将介绍分布式事务和两段提交(two-phase commit, 2PC)。最后会分析自治事务,指出什么是自治事务以及自治事务所扮演的角色。事务控制语句 Oracle中不需要用专门的语句来“开始事务”。事务会在修改数据的第一条语句处隐式开始(也就是得到TX锁的第一条语句)。也可以使用SET TRANSACTION或DBMS_TRANSACTION包来显式地开始一个事务,但是这一步并不是必要的,这与其他的许多数据库不同,因为那些数据库中都必须显式地开始事务。如果发出COMMIT或ROLLBACK语句,就会显式地结束一个事务。 一定要显式地使用COMMIT或ROLLBACK来终
5、止事务;否则,你使用的工异环境就会从中挑一个来结束事务。如果正常地退出SQL*Plus会话,而没有提交或回滚事务,SQL*Plus就会认为你希望提交前面做的工作,并为你完成提交。另一方面,如果你只是退出一个Pro*C程序,就会发生一个隐式的回滚。不要过分依赖这些隐式行为,因为将来这些行为可能会有改变。一定要显式地提交或回滚事务。 ORACLE中的事务是原子性的,这说明无非两种情况:构成事务的每条语句都会提交(成为永久),或者所有语句都回滚。这种保护还延伸到单个的语句。一条语句要么完全成功,要么这条语句完全回滚。注意,我说的是“语句”回滚。如果一条语句失败,并不会导致先前已经执行的语句自动回滚。
6、它们的工作会保留,必须由你来提交或回滚。这里谈到了语句和事务是原子性的,在具体介绍其含义之前,先来看看我们可以使用哪些事务控制语句。COMMIT:要想使用这个语句的最简形式,只需发出COMMIT。也可以更详细一些,写为COMMIT WORK,不过这二者是等价的。COMMIT会结束你的事务,并使得已做的所有修改成为永久性的(持久保存)。COMMIT语句还有一些扩展用于分布式事务中,允许增加一些有意义的注释为COMMIT 加标签(对事务加标签),以及强制提交一个可疑的分布式事务。还有一些扩展,可以让你执 行一个异步提交,这实际上违反了持久性原则。我们会在后面粗略介绍并说明其使用时机。ROLLBAC
7、K:要想使用这个语句的最简形式,只需发出ROLLBACK。同样地,你也可以更锣嗦一些, 写为ROLLBACK WORK,但是二者是等价的。回滚会结束事务,并撤销所有未提交的修改。为此 要读取存储在回滚段/undo段中的信息,并把数据库块恢复到事务开始之前的状态(后面我将把回滚段/undo段统称为undo段,Oracle Database l0g及其后版本中都喜欢用这个词)。SAVEPOINTT: SAVEPOINT 允许你在事务中创建一个标记点(marked point)。一个事务中可以有多个SAVEPOINT。ROLLBACK TO :这个语句与SAVEPOINT命令一起使用。可以把事务回滚
8、到标记点,不回滚在此标记点之前的任何工作。所以,可以发出两条UPDAT语句,后面跟一个SAVEPOINT,然后又是两条DELETE语句。如果执行DELETE语句期间出现了某种异常情况,而且你捕获到这个异常,并发出ROLLBACK TO SAVEPOINT命令,事务就会回滚到指定的SAVEPOINT, 撤销DELETE完成的所有工作,而UPDATE语句完成的工作不受影响。SET TRANSACTION:这条语句允许你设置不同的事务属性,如事务的隔离级别以及事务是只读的 还是可读写的。使用手动undo管理时,还可以使用这个语句来指示事务使用某个特定的undo段,不过不推荐这种做法。我们将在第9章更
9、详细地讨论手动和自动undo管理。就这么多,Oracle中没有别的事务控制语句了。最常用的控制语句就是COMMIT和ROLLBACK.SAVEPOINT语句的用途有点特殊。Oracle在内部频繁地使用了这个语句,实际上Oracle在执行任意SQL或PLISQL语句时都会使用这个语句,而且你会发现这个语句也用在你的应用中。原子性前面对事务控制语句做了一个简要的概述后,下面可以看看语句原子性、过程原子性和事务原子性到底有什么含义。语句级原子性考虑以下语句:看上去很明显,如果该语句由于一个约束冲突而失败,这一行就不会插入。不过,再考虑下面的例子,这里表下上的一个工NSER下或DELE下E会触发一个触
10、发器,它将适当地调整表T2中的CNT列:ops$tkyte%ORA11GRZ create table t2Table t intops$tkyte%ORA11GRZ insert into tz values(o1 row created.ops$tkyte%ORA11GRZCommit complete.ops$tkyte%ORAiiGRZTable mitcreate table tx int check(x0)ops$tkyte%ORA11GR2 ops$tkyte%ORA11GR2 before insert or delete on t for each row begin if(
11、inserting)then update t2 set cnt = cnt +1; else update tz set cnt end if; dbms_ output.put_ line(I fired and updated| sql%rowcount|rows); end; / Trigger created.在这种情况下,会发生什么就不那么显而易见了。如果触发器触发之后出现了错误,触发器的影响是否还存在?也就是说,如果触发器被触发,并且更新了T2,但是这一行没有插入到丁中,结果会是什么?显然答案应该是,如果并没有真正在丁中插入一行,我们就不希望T2中的CNT列递增。幸运的是,在Or
12、acle中,客户最初发出的语句(在这里就是INSERT INTOT)会完全成功或完全失败。这个语句是原子性的。以下可以验证这一点:ops$tkyte%ORA11GR2 set serveroutput onops$tkyte%ORA11GR2 insert into t values(1);I fired and updated 1 rows1 row created.ops$tkyte%ORA11GR2 insert into t values(-1);I fired and updated t rowsinsert into t values(-1)*ERROR at line 1:ORA
13、-02290: check constraint (OPS$TKYTE.SYS_C0018o95) violatedops$tkyte%ORA11GR2 select * from t2; CNT- 1这样一来,丁中成功地插人一行,而且我们也及时地接收到消息:I fired and updated 1 row.下一个州SE盯语句违反了丁上的完整性约束。此时出现了。BMS_OUTPUT消息-T上的触发器确实触发了,这个DBMS一OUTPUT消息就是证据。触发器成功地完成了T2的更新。我们可能认为现在T2中CNT的值是2,但是可以看到它的值实际上为1 . Oracle保证最初的INSERT(即导致
14、触发器触发的擂人语句)是原子性的,这个INSERT INTO是语句,所以INSERT INTO的任何连带效果都被认为是该语句的一部分。 为了得到这种语句级原子性,Oracle悄悄地在每个数据库调用外面包了一个SAVEPOINT。前面的两个INSERT实际上处理如下:Savepoint statement1;Insert into t values(1);If error then rollback to statements;Savepoint statement2; Insert into t values(-1);If error then rollback to statement2;对
15、于习惯于使用Sybase或SQL Server的程序员来说,刚开始可能会有点摸不着头脑。在这些数据库中,情况恰恰相反。这些系统中的触发器会独立于触发语句执行。如果触发器遇到一个错误,它必须显式地回滚自己的工作,然后产生另外一个错误来回滚触发语句。否则,即使触发语句(或该语句的另外某个部分)最终会失败,触发器完成的工作也会持久保留。在Oracle中,这种语句级原子性可以根据需要延伸。在前面的例子中,如果INSERT INTO触发了一个触发器,这个触发器会更新另一个表,而那个表也有一个触发器,它会删除第三个表(依次类推),那么要么所有工作都成功,要么无一成功。为保证这一点,无需你编写任何特殊的代码
16、,Oracle本来就会这么做。过程级原子性有意思的是,Oracle把PL/SQL匿名块也当做是语句。请考虑以下存储过程并且重设样例表:ops$tkyte%ORAsiGR2 create or replace procedure p 2 as 3 begin 4 insert into t values(1) 5 insert into t values(-1) 6 end; 7 /Procedure created.ops$tkyte%ORA11GRZ delete from t;o rows deleted.ops$tkyte%ORA11GR2 update t2 set cnt=0;1 r
17、ow updated.ops$tkyte%ORA11GR2 commit;Commit complete.ops$tkyte%ORA11GR2 select*from t;no rows selectedops4TKYTE%ORA11GR2 select*from t2; CNT - 0以上创建了一个过程,而且我们知道这个过程不会成功。在这个过程中,第二个INSERT总会失败。下面来看运行这个存储过程时会发生什么情况:ops$tkyte%ORA11GRZ begin 2 p: 3 end; 4/I fired and updated a rowsI fired and updated a ro
18、wsbegin*ERROR at line 1:ORA-02290: check constraint (OPS$TKYTE.SYS_ 00018095) violatedORA-06512: at OPS$TKYTE.P,line 5ORA-06512: at line 2ops$tkyte%ORA11GR2 select * from t;no rows selectedops$tkyte%ORA11GR2 select * from t2; CNT - 0可以看到,Oracle把这个存储过程调用处理为一个原子语句。客户提交了一个代码块BEGIN P:END; , Oracle在它外面包了
19、一个SAVEPOINT。由于P失败了,Oracle将数据库恢复到调用这个存储过程之前的时间点。现在,如果提交一个稍微不同的代码块,会得到完全不同的结果:ops$tkyte%ORA11GR2 begin 2 P; 3 exception 4 when others then 5 dbms_output.put_ line(Error! | sqlerrm); 6 end; 1/I fired and updated a rowsI feed and undated s rowsError!l!ORA-02290: check constraint (OPS$TKYTE.SYS_CO018095)
20、 violatedPL/SQL procedure successfully completed.ops$tkyte%ORA11GR2 select*from t; X - 1ops$tkyte%ORA11GR2 select*from t2; CNT - 1ops$tkyte%ORA11GR2 rollback;Rollback complete.在此,我们运行的代码块会忽略所有错误,这两个代码块的输出结果有显著的差别。尽管前面第一个户调用没有带来任何改变,但在这里的P调用中,第一个INSERT会成功,而且T2中的CNT列会相应地递增。Oracle认为客户提交的代码块是“语句”。这个语句之所
21、以会成功,因为它自行捕获并忽略了错误,所以If error then rollback没有起作用,而且执行这个语句后Oracle没有回滚到SAVEPOINTO,因此,这就保留了P完成的部分工作。为什么会保留这一部分工作呢?首要的原因是P中有语句级原子性:P中的每条语句都具有原子性。P提交其两条INSERT语句时就成为Oracle的客户。每个INSERT要么完全成功,要么完全失败。从以下事实就可以证明这一点:可以看到,T上的触发器触发了两次,而且将T2更新了两次,不过T2中的计数只反映了一个UPDATE。P中执行的第二个INSERT外包着一个隐式的SAVEPOINT.事务级原子性事务(也就是一组
22、SQL语句作为一个工作单元一同执行)的总目标是把数据库从一种一致状态转变为另一种一致状态。为了实现这个目标,事务也是原子性的,事务完成的所有工作要么完全提交并成为永久性的,要么会回滚并撤销。像语句一样,事务是一个原子性的工作单元。提交一个事务后,接收到数据库返回的“成功”消息后,你就能知道事务完成的所有工作都已经成为永久性的。DDL与原子性需要指出,Oracle中有一类语句具有原子性,不过只是在语句级保证原子性。数据定义语言(DataDefinition Language, DDL)语句采用了一种特定的实现方式,可以完成如下工作。(1)提交所有未完成的工作,结束当前已有的所有事务。(2)完成D
23、DL操作,如CREATE TABLE。(3)如果DDL操作成功则提交,否则回滚DDL操作。这说明,只要发出CREATE, ALTER等DDL语句,就可以将现有的事务立即提交,并完成后面的DDL命令,这些DDL命令可能提交从而得到持久结果,也可能因出现错误而回滚。尽管DDL井不违反ACID概念,但DDL语句会提交的这一点确实需要注意。持久性通常情况下,一个事务提交时,它的改变就是永久性的。即使数据库在提交完成之后随即崩溃,你也完全可以相信这些改变确实已经永久存储在数据库中。不过,下述两种特定情况例外。使用COMMIT语句新增的WRIT扩展(这是。racle Database l 0g Relea
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- oracle 事务 transaction 信息管理 信息系统 学士学位 论文
限制150内