数据一致性与事务管理_第1页
数据一致性与事务管理_第2页
数据一致性与事务管理_第3页
数据一致性与事务管理_第4页
数据一致性与事务管理_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第19章数据一致性与事务管理数据库中,除了数据的完整性之外,数据的一致性同样是一个重要的话题。而事务是保证数据一致性的重要手段。本章主要讲解数据的一致性,以及事务的管理。本章的主要内容包括:数据一致性简介;事务简介;Oracle中的事务处理;事务处理的原则。19.1什么是数据一致性和事务数据一致性是指数据库的数据在每一时刻都是稳定、而且是可靠的状态。而事务是保证数据一致性的主要手段。19.1.1数据一致性对于一个数据库来说,其中的数据可能是每时每刻都在发生着变化,而在数据变化的同时,也无时无刻不伴随着数据的读取。这就对数据库的状态产生了比较高的要求——数据库的每次改变都是可被接受的,而每次读取的数据也都是正常的。这就是数据一致性的体现。例如,在某个用户的银行账户中,现有存款100元。此时,如果一个用户读取其中的数据为100元,那么,此时的100元是可以接受的数据。但在同一时刻,另一用户针对同一账户进行了以下操作,向其中存入了100元,但是还没有提交动作,那么,此时第一个用户有可能会读到200元的余额。事实上,由于某些原因,第二个用户的提交没有成功,那么第一个用户所读取的200元,并非数据库的真实和可靠的状态。这就造成了读不一致性。另外一种情形,如果第一个用户读取了200元的同时,取出了100元,那么计算获得余额为100元。而第二个用户的存款动作失败,最后,第一个用户的余额重新覆盖数据库中的数据,那么就会将100再次写回数据库,这造成了取出100元,最后余额还为100元的状态,此时的数据库也不符合一致性的状态。19.1.2事务在数据库中,提出了事务的概念来保证数据库中数据的一致性。事务往往包括一个或多个处理步骤。例如,在超市购物包括,选购商品、放入购物车、付款、个人现金或银行账户余额减少、超市账户余额增加、商品库中商品信息更新等步骤。这些步骤组成了一个事务,当其中任何步骤出现异常,并且不能正常进行下去,都会影响其他所有步骤。例如,付款阶段不能正常进行,那么将不会对个人的现金或银行账户造成影响,超市的账户也不可能进行余额的增加,商品库中也不能更新该商品的信息。同样的,如果个人现金或账户余额不足,那么也无法完成整个交易。在此之前所做的所有动作:选购商品、放入购物车等都将无效,商品应当被重新放回货架。19.2Oracle中的事务处理Oracle中的事务应当使用关键字transaction。一个事务的生命周期应当包括:事务开始、事务执行和事务结束。需要注意的是,Oracle中并不能显式开始一个事务,也不存在这样的语句。事务的开始总是隐式进行的,而事务的结束则可以利用commit或者rollback命令进行终止。Oracle中控制事务的常用命令包括:Commit;rollback;savepoint;rollbackto<savepoint>;settransaction;setconstraint。19.2.1commit命令commit命令用于提交事务,并将事务中对数据库的修改进行持久化,即将数据库修改为另外一种状态,而这种状态是可接受的、可靠的状态。whilei<1000loopupdatepeoplesetsalary=salary+10*iwhereid=i;i:=i+1;endloop;commit;对于开发者来说,最安全的方式是显式进行数据的提交或者回滚,以结束事务。但很多时候,许多开发者并未注意该问题,而是依靠开发工具来进行提交或回滚。

此时需要注意的是,如果用户未提交对数据库的修改,而关闭了回话,或者数据库连接在提交之前断开,那么针对该数据库的所有操作都将执行回滚操作。19.2.1commit命令另外,需要明确的概念是,在提交之前,数据库已经进行了实际更新,不过,并未得到数据库认可,因此提交动作只是一个获得认可的过程,其花费的数据库资源非常少。而且,提交一条数据与提交1000条数据所花费的数据库资源是相同的。因此,当实现大数据量的数据修改或者插入操作时,应当采取最后一次性提交的策略。whilei<1000loopupdatepeoplesetsalary=salary+10*iwhereid=i;i:=i+1;commit;endloop;在该代码片段中,每次更新数据,都有一次提交动作,将造成数据库资源的浪费。

19.2.2rollback命令rollback命令用于回滚用户操作。在某些时机,例如程序代码段中出现异常或错误,或者用户直接发出撤销命令,需要回滚操作。回滚操作将终止事务处理,并撤销用户在当前事务中进行的更改。beginwhilei<1000loopupdatepeoplesetsalary=salary+10*iwhereid=i;i:=i+1;endloop;exceptionrollback;end;回滚操作,首先要读取回滚段信息,并利用这些信息将数据库中已发生的修改重新恢复。例如,对于使用了update操作的列,则需要将其恢复到原值,而使用了delete操作的行,则需要再次执行插入操作。因此,回滚操作所需要的时间和花费的资源,依赖于在事务中所执行的数据库更改,并与之成正比。通常情况下,回滚操作是非常耗费时间和资源的,因此,回滚往往被用于处理异常,而不用作终端用户的可操作选项。一旦终端用户经常性使用回滚操作,那么将为数据库带来非常大的负担。应当保证终端用户在提交事务之前进行确认,来代替允许用户执行回滚,从而实现提交与回滚操作的平衡。19.2.3savepoint和rollbacktosavepoint命令通过对rollback的描述可知,rollback命令走向了一个极端——回滚整个事务的所有操作。而有时,大部分的工作都是必须执行的,仅有少量的工作有可能出现异常,并需要回滚。那么,除了利用多个事务进行处理之外,还可以使用savepoint在事务中建立标记点,并允许用户只回滚标记点之后的动作。回滚标记点之后的操作,需要使用rollbacktosavepoint命令。updatepeoplesetid=id-1;beginsavepointinsert_people;updatepeoplesetstatus='CXL';insertintopeople(id,name,status)values(1,'allen','ACT');exceptionwhenothersthenrollbacktoinsert_people;end;19.2.3savepoint和rollbacktosavepoint命令这里需要注意的是,回滚操作虽然回滚了数据库状态,但是并不会改变程序的运行轨迹,也就是说,程序继续执行rollbacktoinsert_people的下一条语句。

updatepeoplesetid=id-1;beginsavepointinsert_people;updatepeoplesetstaus='CXL';insertintopeople(id,name,status)values(2,'allen','ACT');exceptionwhenothersthenrollbacktoinsert_people;end;commit;19.2.4事务的属性和隔离级别事务本身存在着一些属性,这可以保证事务以某种特定的规则运行。所谓隔离,是指将事务所能看到的数据库状态与其他事务分隔开来1.readonly属性settransactionreadonly;insertintopeople(id,name,status)values(13,'youyou','ACT');commit;只读事务的这种特性,可以提供一种稳定的状态,从而处理大量的数据查询工作。例如,在生成复杂报表时,需要查询大量数据,而这些数据又是频繁变更的,在处理报表的过程中,可以利用只读事务来提供稳定的环境,以使生成的报表有意义。19.2.4事务的属性和隔离级别2.readwrite属性readwrite属性可以将事务设置为可读、可写状态。这实际是事务的默认状态,因此,该属性的显式设定,并没有太大的现实意义。需要注意的是,一旦使用settransactionreadwrite命令,那么该命令之前,不能出现settransaction命令之外的其他命令。19.2.4事务的属性和隔离级别3.serializable隔离级别serializable隔离级别是指串行化事务。串行化事务可以实现与只读事务实现相同的功能——隔离其他事务对数据库状态的影响。但是串行化事务允许在其中执行任何DML操作,包括删除、修改、插入数据等。在默认情况下,一个事务可以识别其他事务针对数据库的修改,而这种修改仅限于已经提交到数据库的修改。使用了串行化事务,那么,其他事务已经提交的修改也将被隔离。这里所说的隔离,实际是对于查询操作来说,也就是串行化事务的处理过程中,无法查看到其他事务的修改。settransactionisolationlevelserializable;19.2.4事务的属性和隔离级别4.readcommited隔离级别readcommited隔离级别是事务的默认隔离级别,即只能读取其他事务已经提交的修改。对于尚未提交的修改,只有实现该修改的事务本身可以进行读取。19.3事务处理原则事务处理的原则可以概括为ACID。ACID是以下单词的首字母:原子性(Atomicity):整个事务不可分割,要么全部执行,要么都不执行。一致性(Consistency):事务一旦提交生效,会将数据库从一种状态转变为另一种状态。隔离性(Isolation)隔离性(Isolation):

在事务处理的过程中,事务处理的效果对于其他事务,是完全透明的。持久性(Durablity):一旦提交了事务处理,那么事务处理的效果将永久生效。19.3.1原子性Oracle中的事务处理遵循原子性。无论事务中包含多少语句,要么提交所有工作,要么废除所有工作。需要注意的是,利用savepoint和rollbacksavepoint回滚部分操作并非特例,这是因为利用rollbacksavepoint也是用户指定的动作。可以看做事务处理中的普通命令。createtablet(datavarchar2(2));insertintotvalues('a');insertintotvalues('b');Rollback;select*fromt;19.3.2一致性Oracle中的事务必须保证数据的一致性。数据一致性的一个典型实例为外键约束。例如,在外键约束时,首先更新父表中的主键,如果在子表中有数据与该父表记录相关联,那么父表的更新将被终止。同样地,如果试图更新子表的外键列,也会造成更新失败。因为这两个动作都破坏了数据的一致性。无论哪种操作,如果成功执行,都会使数据库中的数据处于逻辑上的不可接受状态。此时的数据一致性的保持,是在出现在语句级,即每条DML语句都会进行校验。而事务可以包含多条语句,并可以在事务开始执行时将约束设置为延迟校验。以外键约束为例,可以成功避开无法更新父表主键和子表外键的尴尬。但是,提交时,延迟校验将生效,以保持数据一致性。19.3.2一致性createtablevendor(vendor_idintegerprimarykey,vendor_namevarchar2(20));createtablepo(po_idinteger,vendor_idinteger,constraintfk_vendor_poforeignkey(vendor_id)referencesvendordeferrable);insertintovendorvalues(1,'HK');insertintopovalues(1,1);updatevendorsetvendor_id=2;setconstraintsfk_vendor_podeferred;updatevendorsetvendor_id=2;updateposetvendor_id=2;

commit;19.3.3隔离性1.脏读取(DirtyRead)脏读取意味着,可以读取来自外界其他动作对数据库的修改,而这种修改尚未提交,未提交的数据有可能回滚。也就是说,读取的数据并非真正有效的数据,这将直接破坏数据一致性。2.不可重读不可重读意味着,如果用户在某一时刻读取了一条记录,那么,在下一时刻再次读取时,该记录已发生改变。其状态类似于“人不能两次踏入同一条河流”。不可重读并非不可接受的,相反,不可重读是一种正常的数据库状态。这与脏读取是有本质区别的。3.影像读取影像读取意味着,如果用户在某一时刻执行了一个查询,在下一时刻再次执行相同查询时,可能会有新的数据加入。但是,已经读取的数据是不会改变的,只是查询所获得结果集更大而已。19.3.4持久性持久性是指,当事务一旦提交,其改变将会生效,并将信息存储在磁盘上。当系统再次重新启动或者故障时,这些信息不会丢失。对于提交动作来说,用户见到提交成功提示时,Oracle并未完成持久化工作。但是,Oracle数据库利用redo日志文件来保证系统的持久性。redo文件在事务提交的前一刻生成,其中记录了一旦提交时,系统崩溃,那么该如何将事务的工作再次执行,以保证事务真正执行完毕,并持久化到数据库。19.4本章实例本节将通过一个实例查看事务嵌套的处理原则。事务嵌套是指,在事务的处理过程中调用了其他子程序,子程序所完成的功能也是一个事物。【范例19-12】该范例用于演示事务嵌套的处理原则。createtablerecords(recordvarchar2(20));createorreplaceprocedurelocaliscounternumber:=-1;beginselectcount(*)intocounterfromrecords;dbms_output.put_line('子程序,当前记录数为:'||counter);insertintorecordsvalues('该记录来自local');commit;end;19.4本章实例declarecounternumber:=-1;begindeletefromrecords;commit;insertintorecordsvalues('该记录来自Global');local;selectcount(*)intocounterfromrecords;dbms_output.put_line('主程序,当前记录数为:'||counter);rollback;

local;insertintorecordsvalues('该记录来自Gobal');commit;

local;selectcount(*)intocounterfromrecords;dbms_output.put_line('主程序,当前记录数为:'||counter);end;19.4本章实例declarecounternumber:=-1;begindeletefromrecords;commit;insertintorecordsvalues('该记录来自Global');lo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论