隔离级别

详细说明:

当多个用户访问同一数据库时会发生的现象介绍如下:

在单用户环境中,每个事务都是顺序执行的,而不会遇到与其他事务的冲突。但是,在多用户环境下,多个事务可以(而且常常)同时执行。因此每个事务都有可能与其他正在运行的事务发生冲突。有可能与其他事务发生冲突的事务称为交错的 或并行的 事务,而相互隔离的事务称为串行化 事务,这意味着同时运行它们的结果与一个接一个连续地运行它们的结果没有区别。在多用户环境下,在使用并行事务时,会发生四种现象:

丢失更新:这种情况发生在两个事务读取并尝试更新同一数据时,其中一个更新会丢失。例如:事务 1 和事务 2 读取同一行数据,并都根据所读取的数据计算出该行的新值。如果事务 1 用它的新值更新该行以后,事务 2 又更新了同一行,则事务 1 所执行的更新操作就丢失了。由于设计 DB2 的方法,DB2 不允许发生此类现象。

脏读:当事务读取尚未提交的数据时,就会发生这种情况。例如:事务 1 更改了一行数据,而事务 2 在事务 1 提交更改之前读取了已更改的行。如果事务 1 回滚该更改,则事务 2 就会读取被认为是不曾存在的数据。

不可重复的读:当一个事务两次读取同一行数据,但每次获得不同的数据值时,就会发生这种情况。例如:事务 1 读取了一行数据,而事务 2 在更改或删除该行后提交了更改。当事务 1 尝试再次读取该行时,它会检索到不同的数据值(如果该行已经被更新的话),或发现该行不复存在了(如果该行被删除的话)。

幻像:当最初没有看到某个与搜索条件匹配的数据行,而在稍后的读操作中又看到该行时,就会发生这种情况。例如:事务 1 读取满足某个搜索条件的一组数据行,而事务 2 插入了与事务 1 的搜索条件匹配的新行。如果事务 1 再次执行产生原先行集的查询,就会检索到不同的行集。

维护数据库的一致性和数据完整性,同时又允许多个应用程序同时访问同一数据,这样的特性称为并发性。 DB2 数据库用来尝试强制实施并发性的方法之一是通过使用隔离级别——通过‘事务、隔离级别、锁’机制,它决定在第一个事务访问数据时,如何对其他事务锁定或隔离该事务所使用的数据。 DB2 使用下列隔离级别来强制实施并发性:

可重复的读(Repeatable Read)

读稳定性(Read Stability)

游标稳定性(Cursor Stability)

未提交的读(Uncommitted Read)

可重复的读隔离级别可以防止所有现象,但是会大大降低并发性的程度(可以同时访问同一资源的事务数量)。未提交的读隔离级别提供了最大的并发性,但是后三种现象都可能出现。

DB2 UDB 支持以下隔离级别:

可重复读(Repeatable read,RR);

读稳定性(Read stability,RS);

游标稳定性(Cursor stability,CS);

未提交读(Uncommitted read,UR)。

下面分别讲述:

可重复读(Repeatable read,RR) 确保 工作单元(UOW)期间的任何表行读操作直到 UOW 完成,不会被其他应用程序进程更改。类似地,由另一个应用程序进程更改的任何行直到由该应用程序进程提交,不会被读取。运行在 RR 级别的应用程序进程是完全与并发应用程序进程的效果相隔离的。RR 隔离级别通常会直接对表加 S 锁,所以对并发的影响最大,但有一种情况例外:如果 WHERE 条件字段上建有主键或者 UNIQUE INDEX,并且通过主键或者 UNIQUE INDEX 进行查询,那么数据库将只对表加 IS 锁,结果行加 S 锁——在锁列表足够用,没有发生锁升级的情况下才成立,也就是说,这个时候 RR 级别 =RS 级别,这时不允许其他事务对这些行进行更新或者删除,因为对行的更新或者删除会对相应的行加 X 锁,这和行 S 锁相排斥;其他情况下,会直接对表加 S 锁,这时将不允许其他事务对任何行进行更新或者删除。

读稳定性(Read stability,RS)类似于 RR 。但是,运行在 RS 级别的应用程序进程不是完全与并发应用程序进程的效果相隔离的。如果这样的应用程序进程不止一次发出同样的查询,它就会看到更改了的数据或者由其他应用程序进程添加的新的“幻影(phantom)”行。RS 隔离级别会对表加 IS 锁,结果行加 NS 锁,这时不允许其他事务对这些行进行更新(UPDATE/DELETE),但是允许插入任何行,因为对这些行的更新会对相应的行加 X 锁,这和行 NS 锁相排斥——上述说法基于锁列表足够用,没有发生锁升级的情况下才成立。

游标稳定性(Cursor stability,CS)也确保由另一个应用程序进程更改的任何行直到被那个应用程序进程提交,不会被读取。 CS 隔离级别只确保每个可更新游标的当前行不被其他应用程序进程更改;在 UOW 期间读过的行可以被其他应用程序进程更改。针对可滚动更新游标,在提交之前,会对所有结果行一直加 U 锁,无论游标滚动到什么地方; CS 隔离级别针对不可更新游标会对表加 IS 锁,如果未在 WHERE 条件字段上创建索引,查询首先会查找锁列表,检查锁列表中是否存在与 IS 锁相排斥的锁,如果存在的话,那么将等待所有持有排斥锁的事务提交,查询才能执行下去;如果 WHERE 条件字段创建了索引,并且使用了索引,那么查询将通过索引得到结果行,然后检查锁列表中是否存在与结果行相排斥的锁,如果存在的话,那么将等待所有持有排斥锁的事务提交,查询才能执行下去 .

未提交读(Uncommitted read,UR)对于某些操作,允许在 UOW 期间读过的任何行可以被其他应用程序进程更改,并允许读任何被另一个应用程序进程更改过的行,即使该更改还没有提交。对于其他操作,UR 类似于 CS 。综上所述,离级别对并发性具有最显著的影响,不同隔离级别获得的资源的锁定范围也不同,如果所有事务都能做到不过分贪婪的占有锁资源——锁的范围大、占用时间长,那么事务之间发生锁冲突的可能性将大大降低,事务的并发性也将会很好。那么如何选择正确的隔离级别呢?

使用的隔离级别不仅影响数据库对并发性的支持如何,而且影响并发应用程序的性能。通常,使用的隔离级别越严格,并发性就越小,某些应用程序的性能可能会越低,因为它们要等待资源上的锁被释放。那么,如何决定要使用哪种隔离级别呢?最好的方法是确定哪些现象是不可接受的,然后选择能够防止这些现象发生的隔离级别:

如果正在执行大型查询,而且不希望并发事务所做的修改导致查询的多次运行返回不同的结果,则使用可重复的读隔离级别。

如果希望在应用程序之间获得一定的并发性,还希望限定的行在事务执行期间保持稳定,则使用读稳定性隔离级别。

如果希望获得最大的并发性,同时不希望查询看到未提交的数据,则使用游标稳定性隔离级别。

如果正在只读的表 / 视图 / 数据库上执行查询,或者并不介意查询是否返回未提交的数据,则使用未提交的读隔离级别。 对于统计类报表,不需要得到十分精确的数据,那么最好使用 UR 隔离级别,既可以节省昂贵的锁列表资源,也不会因为锁冲突影响其他事务的执行,同时也不会受到其他事务的影响,顺利的得到统计结果。未提交的读隔离级别通常用于那些访问只读表和视图的事务,以及某些执行 SELECT 语句的事务(只要其他事务的未提交数据对这些语句没有负面效果)。 顾名思义,其他事务对行所做的更改在已经提交之前对于使用未提交的读隔离级别的事务是可见的。但是,此类事务不能看见或访问其他事务所创建的表、视图或索引,直到那些事务被提交为止。类似地,如果其他事务删除了现有的表、视图或索引,那么仅当进行删除操作的事务终止时,使用未提交的读隔离级别的事务才能知道这些对象不再存在了。(一定要注意一点:当运行在未提交的读隔离级别下的事务使用可更新游标时,该事务的行为和在游标稳定性隔离级别下运行一样,并应用游标稳定性隔离级别的约束。)

时间: 2024-08-02 10:19:34

隔离级别的相关文章

数据库事务的四大特性和事务隔离级别

Reference: [1] http://www.cnblogs.com/fjdingsd/p/5273008.html [2] http://blog.csdn.net/fg2006/article/details/6937413 数据库事务四大特性 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全

数据库事务隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committed.Repeatable read.Serializable,这四个级别可以逐个解决脏读.不可重复读.幻读这几类问题. √: 可能出现    ×: 不会出现   脏读 不可重复读 幻读 Read uncommitted √ √ √ Read committed × √ √ Repeatable read × × √ Serializable × × × 注意:我们讨论隔离级别的场景,主要是在多个

数据库事务的隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committed.Repeatable read.Serializable,这四个级别可以逐个解决脏读.不可重复读.幻读这几类问题. √: 可能出现    ×: 不会出现   脏读 不可重复读 幻读 Read uncommitted √ √ √ Read committed × √ √ Repeatable read × × √ Serializable × × × 注意:我们讨论隔离级别的场景,主要是在多个

深入分析事务的隔离级别

本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接是互不影响的,所以,在多个事务并发操作的过程中,如果控制不好隔离级别,就有可能产生脏读.不可重复读或

MySQL事务隔离级别详解

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销.Read Uncommitted(读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读(Dirty Read).Read Committed(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的).

事务的特性及事务的隔离级别(转)

原文:http://www.cnblogs.com/fjdingsd/p/5273008.html 本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响. ⑵ 一致性(Consi

mysql 隔离级别和锁相关

mysql数据库中存在三种锁,间隙锁(gap-lock) , 行锁(record-lock),gap-record-lock gap-record-lock 是间隙锁和行锁的组合, 间隙锁(gap lock) 行锁(record lock) record-lock: 测试表: CREATE TABLE `tt` ( `tid` int(11) NOT NULL DEFAULT '0', `tname` varchar(10) DEFAULT NULL, `tage` tinyint(4) DEF

《高性能MySQL》读书笔记--锁、事务、隔离级别 转

1.锁 为什么需要锁?因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对表中同一行记录进行操作,比如有的在读取该行数据,其他的尝试去删除它.为了保证数据的一致性,数据库就要对这种并发操作进行控制,因此就有了锁的概念. 1.1锁的分类 从对数据操作的类型(读\写)分 读锁(共享锁):针对同一块数据,多个读操作可以同时进行而不会互相影响. 写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁. 大多数时候,MySQL锁的内部管理都是透明的. 1.2锁粒度(Lock granula

Spring五个事务隔离级别和七个事务传播行为

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重复读 :是指在一个事务内,多次读同一数据.在这个事务还没有结束时,另外一个事务也访问该同一数据.那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的.这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读.例如,一个编辑人员两次读取同一文档,但在两次读取之间

mysql 事务的四种隔离级别

MYSQL标准定义了4种隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的. 低的隔离级一般支持更高的并发处理,并拥有更低的系统开销. 隔离级别由低到高:Read Uncommitted < Read Committed < Repeatable Read < Serializable. 第一:READ UNCOMMITTED (读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交(commit)事务的执行结果. 本隔离级别很少用于实际应用,因为它的性能也不比其他级别好