Copyright©SysTopCorporation,2005.Allrightsreserved.事务2-50目标通过本章学习,您将可以:•使用DML语句•向表中插入数据•更新表中数据•从表中删除数据•将表中数据和并•控制事务3-50事务概念包含一组数据库命令,构成单一逻辑工作单元的操作集合访问并可能更新各种数据项的一个程序执行单元,是不可分割的工作逻辑单元执行并发操作的最小控制单位4-50事务的特性•原子性(A-Atomicity)•一致性(C-Consistency)•隔离性(I-Isolation)•持久性(D-Durability)5-50原子性、一致性•原子性:就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全回滚,全部不保留•一致性:事务完成或者撤销后,都应该处于一致的状态6-50隔离性、永久性•隔离性多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,不合理的存取和不完整的读取数据•永久性事务提交以后,所做的工作就被永久的保存下来7-50事务并发处理会产生的问题•丢失更新当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。8-50丢失更新:假设产品的当前库存60,现有两个事务:T1购入400个,T2卖出40顺序事务步骤存储的值1T1读在库数量602T2读在库数量603T1在库数量=60+4004T2在库数量=60-405T1写在库数量460(将被丢失)6T2写在库数量209-50正常执行过程:假设产品的当前库存60,现有两个事务:T1购入400个,T2卖出40顺序事务步骤存储的值1T1读在库数量602T1在库数量=60+4003T1写在库数量4604T2读在库数量4605T2在库数量=460-406T2写在库数量42010-50•脏读当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。•…11-50T2使用T1未提交数据:假设产品的当前库存60,现有两个事务:T1购入400个,在没有提交前撤消了该操作,T2卖出40顺序事务步骤存储的值1T1读在库数量602T1在库数量=60+4003T1写在库数量4604T2读在库数量460(读未提交数据)5T2在库数量=460-406T1rollback606T2写在库数量42012-50正常执行过程:假设产品的当前库存60,现有两个事务:T1购入400个,在没有提交前撤消了该操作,T2卖出40顺序事务步骤存储的值1T1读在库数量602T1在库数量=60+4003T1写在库数量4604T1RollBack605T2读在库数量606T2在库数量=60-407T2写在库数量2013-50脏读•会话A–Updateempsetsal=2000whereename=‘SCOTT’;•会话B–Selectsalfromempwhereename=‘scott’;14-50数据库事务数据库事务由以下的部分组成:•一个或多个DML语句•一个DDL语句•一个DCL语句15-50数据库事务•以第一个DML语句的执行作为开始•以下面的其中之一作为结束:–COMMIT或ROLLBACK语句–DDL或DCL语句(自动提交)–用户会话正常结束–系统异常终了16-50•showautocommit•setautocommiton;17-50Commit•事务提交命令。•在Oracle中,在内存中将为每个客户机建立工作区,客户机对数据库进行操作处理的事务都在工作区内完成,只有在输入commit命令后,工作区内的修改内容才写入到数据库上,称为物理写入.•这样可以保证在任意的客户机没有物理提交修改以前,别的客户机读取的后台数据库中的数据是完整的、一致的.18-50COMMIT和ROLLBACK语句的优点使用COMMIT和ROLLBACK语句,我们可以:•确保数据完整性。•数据改变被提交之前预览。•将逻辑上相关的操作分组。•当执行了Commit语句之后,会确认事务变化、结束事务、删除保存点、释放锁。当使用commit语句后,其他会话将可以看到事务变化后的新数据19-50ORACLE事务控制-回退段•ORACLE为了适应事务控制设置了回退段这一数据库对象.系统利用回退段来确保诸如读一致性、数据库恢复等管理功能。•ORACLE在缺省情况下,读数据不加锁,通过回退段(RollbackSegment)保证用户不读脏数据和可重复读.•表空间中的数据按段来组织,数据段、索引段、暂存段和回退段,回退段是一块磁盘存储区域,回退段可以由用户创建,但只能由系统进程使用。20-50ORACLE事务控制-回退段•事务的执行过程(采用日志和回退段双重记录事务活动):进入回退段,写入回退信息从数据段读入缓冲区,SQL处理记载日志文件提交,写更改结果到磁盘回退,写回退信息到磁盘事务第一条更新语句事务结束NY21-50Updatetsetcol=‘0’wherecol=‘123’;commit;•数据库首先把该语句的整个操作包括数据‘0’与‘123’写入日志缓冲区•然后把‘123’和一些信息写入回滚段,•最后把‘0’修改到数据缓冲区。•当发出提交命令时,如果日志缓冲区内容没有写入日志文件则必须写入日志文件,回滚段把该事务标记为已经提交,数据缓冲区中的这个事务也标记为已提交•如果回退这个事务,则数据库将回滚段中123读出写回数据缓冲区,这个回退变化也被写入日志文件。22-50自动提交事务•当执行DDL语句时会自动提交事务,•当执行DCL语句(grantrevoke)•当退出SQL*Plus时23-50将某一事务设为只读事务•Settransactionreadonly•只读事务,不生成回滚信息,在整个事务中就不能有修改操作•注意是针对当前事务,不是另一个事务•Settransaction{readonly|readwrite}•通过rollback取消设定。24-50只读事务•只读事务只允许执行查询操作,而不允许执行任何DML操作事务。•当使用只读事务可以确保取得特定的时间点的数据。•例如:–假定企业需要在每天16点统计最近24小时的销售信息,而不统计当天16点之后的销售信息,那么用户可以使用只读事务。–在设置了只读事务之后,尽管其他事务可能会提交新事务,但只读事务不会取得新的数据变化。25-50示例:•会话A:Settransactionreadonly;•会话B:Updateempsetsal=3000whereename=‘SMITH’;•会话A:Selectsalfromempwhereename=‘SMITH’;•Settransactionisolationlevelserializable;–顺序事务,在只读事务的基础特性上还可以对数据进行DML操作26-50控制事务保存点B保存点ADELETEINSERTUPDATEINSERTCOMMITTime事务ROLLBACKtoSAVEPOINTBROLLBACKtoSAVEPOINTAROLLBACK27-50UPDATE...SAVEPOINTupdate_done;Savepointcreated.INSERT...ROLLBACKTOupdate_done;Rollbackcomplete.回滚到保留点•使用SAVEPOINTSAVEPOINTname语句在当前事务中创建保存点。•使用ROLLBACKTOSAVEPOINTname语句回滚到创建的保存点。•用于取消部分事务28-50•自动提交在以下情况中执行:–DDL语句。–DCL语句。–不使用COMMIT或ROLLBACK语句提交或回滚,正常结束会话。•会话异常结束或系统异常会导致自动回滚。事务进程29-50提交或回滚前的数据状态•改变前的数据状态是可以恢复的•其他用户不能看到当前用户所做的改变,直到当前用户结束事务。•DML语句所涉及到的行被锁定,其他用户不能操作。30-50提交后的数据状态•数据的改变已经被保存到数据库中。•改变前的数据已经丢失。•所有用户可以看到结果。•锁被释放,其他用户可以操作涉及到的数据。•所有保存点被释放。31-50COMMIT;Commitcomplete.•改变数据•提交改变DELETEFROMemployeesWHEREemployee_id=99999;1rowdeleted.INSERTINTOdepartmentsVALUES(290,'CorporateTax',NULL,1700);1rowinserted.提交数据32-50数据回滚后的状态使用ROLLBACK语句可使数据变化失效:•数据改变被取消。•修改前的数据状态可以被恢复。•锁被释放。DELETEFROMcopy_emp;22rowsdeleted.ROLLBACK;Rollbackcomplete.33-50语句级回滚•单独DML语句执行失败时,只有该语句被回滚。•Oracle服务器自动创建一个隐式的保留点。•其他数据改变仍被保留。•用户应执行COMMIT或ROLLBACK语句结束事务。34-50锁Oracle数据库中,锁是:•并行事务中避免资源竞争。•避免用户动作。•自动使用最低级别的限制。•在事务结束结束前存在。•两种类型:显示和隐式。35-50锁•两种模式:–独占锁:屏蔽其他用户。–共享锁:允许其他用户操作。•高级别的数据并发性:–DML:表共享,行独占–Queries:不需要加锁–DDL:保护对象定义•提交或回滚后锁被释放。36-50•排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。•共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。37-50加锁方法•自动加锁–INSERTUPDATEDELETE•人工加锁–SELECT…FORUPDATEOF–LOCKTABLEIN锁类型MODE38-50•基本的锁类型有两种:•排它锁[Exclusivelocks]记为X锁•共享锁[Sharelocks]记为S锁•OracleDML锁共有两个层次,即行级锁和表级锁。–Oracle的TX锁(行级锁、事务锁)–TM锁(表级锁)39-50•Oracle的DML锁(数据锁)•其行级锁虽然只有一种(即X锁),•但其TM锁(表级锁)类型共有5种,–共享锁(S锁)、排它锁(X锁)、行级共享锁(RS锁)、行级排它锁(RX锁)、共享行级排它锁(SRX锁),–注意:Oracle在行级只提供X锁,所以与RS锁(通过SELECT…FORUPDATE语句获得)对应的行级锁也是X锁(但是该行数据实际上还没有被修改)。40-50•当Oracle执行SELECT…FORUPDATE、INSERT、UPDATE、DELETE等DML语句时,系统自动在所要操作的表上申请表级RS锁(SELECT…FORUPDATE)或RX锁(INSERT、UPDATE、DELETE),当表级锁获得后,系统再自动申请TX锁,并将实际锁定的数据行的锁标志位置位(指向该TX锁);•也可以通过LOCKTABLE语句来指定获得某种类型的TM锁。下表总结了Oracle中各SQL语句产生TM锁的情况:41-50Oracle中各SQL语句产生TM锁的情况:42-50自动加锁•Oracle自动加锁有4种类型•数据锁–行级锁数据锁是防止多个事务对同一个表或表中同一行操作时产生的冲突–当事务执行以下DML语句,INSERTUPDATEDELETESELECT…FORUPDATEOF..–表级锁当事务获得行锁后,此事务也自动获得表级共享锁,以防止其他事务进行DDL语句同样可以使用LOCKTABLE人工定义表