您的位置:首页 > 数据库 > Oracle

Oracle事务管理知识整理

2011-05-23 13:14 183 查看
事物管理是数据库处理的核心。为了让大量用户执行并发事物,DBMS必须管理事物,使冲突最少,同时保证数据库的一致性。事务管理保证许多用户可同时访问一个数据库,并且用户不能相互撤销工作。

那么什么是事物呢?事物是一个逻辑单元,由一条或多条SQL语句组成。事物有四个特性,原子性,一致性,隔离性,持久性

原子性:一个事物或者完全执行,或者完全不执行,即不能让数据库仅执行一个事物的一部分。例如,如果发出删除一条删除1 000个记录的SQL语句,如果数据库在事物删除999个记录后崩溃,则整个事物中止(回滚)

一致性:数据库被保持在一致的状态。例如,在一个涉及从储蓄账户支付并存入支票账户的银行事物中,数据库不能只把款项存入支票账户就停止。这将导致数据不一致,事物的一致性特性保证数据库不会将数据停留在不一致的状态。所有事物都必须保持数据库的一致性。

隔离性:隔离性表示虽然允许多个事物并发访问数据库,但每个事物必须是孤立执行的。事物的隔离性保证在其他事物提交前看不到相应事物所做的更改。这个特性是由数据库的并发性控制机制支持的。

持久性:保证数据库永久保留提交的事物。完成一个事物之后,数据库保证该事物的更改不会丢失。

为了保证数据的一致性,每个用户必须看到一致的数据集,它包含该用户的事物以及其他用户事物所做的所有更改。在单用户的数据库中,达到数据的一致性是一件很容易的事情。但是,现实的数据库需要允许众多的用户同时操作,这就是所谓的数据并发性。事物中不恰当的交互可能会导致数据不一致。并发控制的一种方案是在每个操作期间锁定整个表,因此,一个用户的事物不会影响另一个用户的事物。这样,每个用户的操作被隔离。这样,每个用户的操作被隔离,从而牺牲数据的并发性。这表示对表的访问将极大地减少。正如所见,Oracle确实是用锁定机制来保证数据的一致性,但为了保持最大的并发性,锁定采用的是最少限制的方式。

并发性带来的问题

脏读问题:当一个事物读取由另外一个正在进行的事物更新但未永久提交给数据库的数据时,发生脏读。例如,假如事物A刚更新了某个列的值,而它又被事物读取B读取。如果事物A回滚其它更改,不管是故意的还是由于某种原因而中止,怎么办?结果是,已更新的列值也将被回滚。然而,事物B已经读取了该列的新值,但现在它是不正确的值了,因为事物A已经回滚。

幻读问题:假如你从一个表读数据。过一段时间后,又重新执行一遍查询,与此同时,其它用户已经插入新数据到表中。因为你的第二次查询将遇到第一次读时未遇到的行,这就是所谓的“幻读”。幻读问题是由一个事物的两个数据库操作之间出现新数据而导致的。

更新丢失:更新丢失问题是由某事物试图在数据被其它事物更新时读取它所导致的问题。假如事物A正在读一个表的数据,而此数据正被事物B更新,事物B成功完成并提交。如果事物A在事物B成功完成前已经读取数据,则它读取的可能是中间数据。由于两个用户更新了相同的行,并且第二次更新覆盖了第一次的更新,则第一次更新丢失,此时这种不正常的丢失更新便出现了。这是一个事物完成之前允许其它事物读和更新一个表所引起的问题。

不可重复读(模糊读):当一个事物发现它以前读的数据已经被其它事物修改,不可重复读(或模糊读)问题就产生了。假如你在某个时间点访问一个表的数据,稍后又试图访问相同的数据,发现第二次读的数据与第一次的不同了。这种相同事物中不一致的数据导致不可重复读问题。

可以看到,所有数据问题都是由并发访问所导致的,可以肯定地设想,隔离执行的一个事物完成时,总是使数据处于一致状态。如果数据库允许并发访问,则需要考虑所有事物对数据库一致性的累积效果

为此,数据库使用一个进度表,它是一个或多个事物的操作序列。如果所有事物串行地执行,即一个接一个地执行,此进度表也该是串行。如果数据库能够生成一个效果上等价于一个串行进度表的进度表,即使它可能是从一组并发事物导出的,则也称此进度表为串行地进度表。

避免数据异常的一种办法是防止一个以上的用户同时看到或更改数据。但是,这有悖于向用户提供并发访问这一主要目的。为了控制并发性和隔离性之间的平衡,要为每个事物指定一种隔离级别

事物的ISO标准取决于两个关键的事物结束语句:commit和rollback.根据ISO标准,所有事物都以select,update,insert和delete语句开始。任何一个事物都不能看到其他事物的中间结果。第一事物仅在第二事物完成后才能得到它的结果。

ISO事物标准的意义在于保证事物符合原子性和隔离性,以避免并发性问题。所有事物必须保持数据库的一致性。数据库在一个事物开始前是一致的,在事物结束时也必须保持一致的状态。如果你能设计一种方法避免前面提到的问题,那么久能保证数据库的事物之间的高度并发交互。但为此要付出一定的代价。试图减少异常将导致并发性减少。

ISO事物标准使用术语隔离级别来表示数据库允许事物之间影响的程度。隔离定义了由一个操作所引起的变化在何时并如何对数据库中其它的并行操作可视。其它事物的隔离使并发执行的数据库事物看不到其它事物的未完成结果。主要的隔离级别包括串行,可重复读,未提交读和已提交读。

串行:在隔离级别的串行下,所有事物相互之间完全隔离,就好像事物处理以串行方式一个接一个地执行一样。在隔离的串行级别下,执行插入,删除或更新的事物在受DML操作影响的一组数据上放置一个写锁。在隔离事物释放其锁之前,即在该事物处理被提交或回滚时,数据库锁定受影响的数据。由于涉及DML操作的其它事物不得不等待解锁,故那些事物不会读任何“脏”数据。隔离的串行级别还帮助你避免不可重复读,因为随后的事物处理不能更新或删除锁定的数据。由于后面的事物处理不能再第一个事物处理锁定的数据范围内插入任何新行,从而摆脱了幻读数据。

可重复读:可重复读隔离级别保证读一致性,即一个事物在两个不同的时间点从一个表中读数据两次,每次都得到相同的值。这个级别的隔离避免了脏读和不可重复读问题

未提交读:未提交读允许事物读取其它事物未提交前得中间值,它可能会导致并发使用的所有问题。

已提交读:Oracle的默认隔离级别是语句级的已提交读隔离级别。Oracle查询只能看到查询开始时已提交的数据。因为此隔离级别是语句级的,所以每条语句只允许看到该语句开始前已经提交的数据。隔离的已提交的读级别保证在访问Oracle表中特定的行时,该行的数据不会改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: