`
如若_晴
  • 浏览: 108456 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

数据库弱一致性四个隔离级别

阅读更多

原文转自;http://www.cnblogs.com/xwdreamer/archive/2011/01/18/2297042.html

 

SQL-92标准中定义了四个隔离级别,这四个隔离级别在以前版本的SQL Server中即受到支持:

READ UNCOMMITTED

READ UNCOMMITTED是限制性最弱的隔离级别,因为该级别忽略其他事务放置的锁。使用READ UNCOMMITTED级别执行的事务,可以读取尚未由其他事务提交的修改后的数据值,这些行为称为“脏”读。这是因为在Read Uncommitted级别下,读取数据不需要加S锁,这样就不会跟被修改的数据上的X锁冲突。比如,事务1修改一行,事务2在事务1提交之前读取了这一行。如果事务1回滚,事务2就读取了一行没有提交的数据,这样的数据我们认为是不存在的。

READ COMMITTED

READ COMMITTED(Nonrepeatable reads)SQL Server默认的隔离级别。该级别通过指定语句不能读取其他事务已修改但是尚未提交的数据值,禁止执行脏读。在当前事务中的各个语句执行之间,其他事务仍可以修改、插入或删除数据,从而产生无法重复的读操作,或“影子”数据。比如,事务1读取了一行,事务2修改或者删除这一行并且提交。如果事务1想再一次读取这一行,它将获得修改后的数据或者发现这一样已经被删除,因此事务的第二次读取结果与第一次读取结果不同,因此也叫不可重复读。

实验1

query1:事务1

复制代码
--step1:创建实验数据
select * into Employee from AdventureWorks.HumanResources.Employee
alter table Employee add constraint pk_Employee_EmployeeID primary key(EmployeeID)

--step2:设置隔离级别,这是数据库的默认隔离界别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

--step3:开启第一个事务
BEGIN TRAN tran1
    --step4:执行select操作,查看VacationHours,对查找的记录加S锁,在语句执行完以后自动释放S锁
    SELECT EmployeeID, VacationHours
        FROM Employee 
        WHERE EmployeeID = 4;

    --step5:查看当前加锁情况,没有发现在Employee表上面有锁,这是因为当前的隔离界别是READ COMMITTED
    --在执行完step2以后马上释放了S锁.
    SELECT request_session_id, resource_type, resource_associated_entity_id,
        request_status, request_mode, resource_description
        FROM sys.dm_tran_locks
复制代码

查看锁的情况如下图所示,我们发现在只有在数据库级别的S锁,而没有在表级别或者更低级别的锁,这是因为在Read Committed级别下,S锁在语句执行完以后就被释放

query2:事务2

复制代码
--step6:开启第二个事务
BEGIN TRAN tran2;
    --step7:修改VacationHours,需要获得排它锁X,在VacationHours上没有有S锁
    UPDATE Employee 
        SET VacationHours = VacationHours - 8  
        WHERE EmployeeID = 4;

    --step8:查看当前加锁情况
    SELECT request_session_id, resource_type, resource_associated_entity_id,
        request_status, request_mode, resource_description
        FROM sys.dm_tran_locks
复制代码

在开启另外一个update事务以后,我们再去查看当前的锁状况,如下图所示,我们发现在表(Object)级别上加了IX锁,在这张表所在的Page上也加了IX锁,因为表加了聚集索引,所以在叶子结点上加了X锁,这个锁的类型是KEY

然后我们回到事务1当中再次执行查询语句,我们会发现查询被阻塞,我们新建一个查询query3来查看这个时候的锁状况,其查询结果如下,我们可以发现查询操作需要在KEY级别上申请S锁,在Page和表(Object)上面申请IS锁,但是因为Key上面原先有了X锁,与当前读操作申请的S锁冲突,所以这一步处于WAIT状态。

如果此时提交事务2的update操作,那么事务1的select操作不再被阻塞,得到查询结果,但是我们发现此时得到的查询结果与第一次得到的查询结果不同,这也是为什么将read committed称为不可重复读,因为同一个事物内的两次相同的查询操作的结果可能不同

REPEATABLE READ

REPEATABLE READ是比READ COMMITTED限制性更强的隔离级别。该级别包括READ COMMITTED,并且另外指定了在当前事务提交之前,其他任何事务均不可以修改或删除当前事务已读取的数据。并发性低于 READ COMMITTED,因为已读数据的共享锁在整个事务期间持有,而不是在每个语句结束时释放。比如,事务1读取了一行,事务2想修改或者删除这一行并且提交,但是因为事务1尚未提交,数据行中有事务1的锁,事务2无法进行更新操作,因此事务2阻塞。如果这时候事务1想再一次读取这一行,它读取结果与第一次读取结果相同,因此叫可重复读。

实验2

query1:事务1

复制代码
--step1:创建实验数据
select * into Employee from AdventureWorks.HumanResources.Employee
alter table Employee add constraint pk_Employee_EmployeeID primary key(EmployeeID)

--step2:设置隔离级别
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

--step3:开启第一个事务
BEGIN TRAN tran1
    --step4:执行select操作,查看VacationHours
    SELECT EmployeeID, VacationHours
        FROM Employee 
        WHERE EmployeeID = 4;

    --step5:查看当前加锁情况,发现在Employee表上面有S锁,这是因为当前的隔离界别是REPEATABLE READ
    --S锁只有在事务执行完以后才会被释放.
    SELECT request_session_id, resource_type, resource_associated_entity_id,
        request_status, request_mode, resource_description
        FROM sys.dm_tran_locks
复制代码

查询锁状态的结果如下图所示,我们发现在KEY上面加了S锁,在Page和Object上面加了IS锁,这是因为在Repeatable Read级别下S锁要在事务执行完以后才会被释放

 query2:事务2

复制代码
--step6:开启第二个事务
BEGIN TRAN tran2;
    --step7:修改VacationHours,需要获得排他锁X,在VacationHours上有S锁,出现冲突,所以update操作被阻塞
    UPDATE Employee 
        SET VacationHours = VacationHours - 8  
        WHERE EmployeeID = 4;
复制代码

执行上述update操作的时候发现该操作被阻塞,这是因为update操作要加排它锁X,而因为原先的查询操作的S锁没有释放,所以两者冲突。我们新建一个查询3执行查询锁状态操作,发现结果如下图所示,我们可以发现是WAIT发生在对KEY加X锁的操作上面。

此时再次执行查询1中的select操作,我们发现查询结果跟第一次相同,所以这个叫做可重复读操作。但是可重复读操作并不是特定指两次读取的数据一模一样,Repeatable Read存在的一个问题是幻读,就是第二次读取的数据返回的条目数比第一次返回的条目数更多。

比如在Repeatable Read隔离级别下,事务1第一次执行查询select id from users where id>1 and id <10,返回的结果是2,4,6,8。这个时候事务1没有提交,那么对2,4,6,8上面依然保持有S锁。此时事务2执行一次插入操作insert into user(id) valuse(3),插入成功。此时再次执行事务1中的查询,那么返回结果就是2,3,4,6,8。这里的3就是因为幻读而出现的。因此可以得出结论:REPEATABLE READ隔离级别保证了在相同的查询条件下,同一个事务中的两个查询,第二次读取的内容肯定包换第一次读到的内容。

SERIALIZABLE 

SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。该级别包括REPEATABLE READ,并增加了在事务完成之前,其他事务不能向事务已读取的范围插入新行的限制。比如,事务1读取了一系列满足搜索条件的行。事务2在执行SQL statement产生一行或者多行满足事务1搜索条件的行时会冲突,则事务2回滚。这时事务1再次读取了一系列满足相同搜索条件的行,第二次读取的结果和第一次读取的结果相同。

重复读与幻读

重复读是为了保证在一个事务中,相同查询条件下读取的数据值不发生改变,但是不能保证下次同样条件查询,结果记录数不会增加。

幻读就是为了解决这个问题而存在的,他将这个查询范围都加锁了,所以就不能再往这个范围内插入数据,这就是SERIALIZABLE 隔离级别做的事情。

隔离级别与锁的关系

  1. 在Read Uncommitted级别下,读操作不加S锁;
  2. 在Read Committed级别下,读操作需要加S锁,但是在语句执行完以后释放S锁;
  3. 在Repeatable Read级别下,读操作需要加S锁,但是在事务提交之前并不释放S锁,也就是必须等待事务执行完毕以后才释放S锁。
  4. 在Serialize级别下,会在Repeatable Read级别的基础上,添加一个范围锁。保证一个事务内的两次查询结果完全一样,而不会出现第一次查询结果是第二次查询结果的子集。

 

分享到:
评论

相关推荐

    数据库事务的四大特征以及隔离级别

    一致性(Consistency):一个事务执行之前和执行之后都必须处于一致性状态。 隔离性(Isolation):并发的事务是相互隔离的,即一个事务内部的操作及正在操作的数据必须封锁起来,不能被其他企图修改的事务看到。 ...

    MySQL数据库:事务隔离级别.pptx

    隔离性强制对事务进行某种程度的隔离,保证应用程序在事务中看到一致的数据。 MySQL提供了下面4种隔离级:序列化(SERIALIZABLE)、可重复读(REPEATABLE READ)、提交读(READ COMMITTED)、未提交读(READ ...

    数据库事务以及事务的隔离级别

     事务的四个属性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。  1.原子性(Atomic)  重要的原则,也是容易理解的原则。被事务管理的所有方法,要么一起被提交,...

    (详细)事务特性和隔离级别

    一致性(Consistency):事务执行完毕后,数据库结果与业务规则一致。如转账业务,无论成功与失败,前后金额总和不变。 隔离性(Isolation):并发的数据库事务操作场景下,各事务间相互隔离,互不影响。 持久性...

    数据库事务隔离级别

     Consistency:一致性  Isolation:隔离性  Duration:持久性  在SQL标准中定义了事务的四种隔离级别:  1,read uncommitted 未提交读  事务中的改动。即使没有提交,对其它事务也都是可见的。即事务能够...

    通过实例分析MySQL中的四种事务隔离级别

    在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。数据库事务的隔离级别有4个,下面话不多说了,来一起看看详细的介绍吧。 数据库事务有四种隔离级别: 未提交读(Read Uncommitted):允许脏...

    JDBC专题(六)-JDBC专题-事务的隔离级别.docx

    •一致性(Consistency) 官网上事务一致性的概念是:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。以转账为例子,A向B转账,假设转账之前这两个用户的钱加起来总共是2000,那么A向B转账之后,不管这...

    深入理解Mysql的四种隔离级别

    一、首先什么是事务?...事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。  1 、原子性。事务是数据库的逻辑工

    数据库面试题集.docx

    答:数据库事务Transaction正确执行的四个基本要素:ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不...

    2019-8-7-MySQL的四种事务隔离级别1

    2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据

    事务隔离级别和脏读的快速入门

    一些数据库宣称自己具有“最终一致性”,但却可能对重复查询返回不一致的结果。相比于你所寻求的数据库,一些数据库提供更高的事务隔离级别。脏读可导致同一记录得到两个版本,或是完全地丢失一条记录。在同一事务中...

    哈尔滨理工大数据库试题

    B. 一致性 C. 独立性 D. 完整性 2、 关系模式R中的属性全部都是主属性,则R的最高范式必定是D。 A. 2NF B. 3NF C. BCNF D. 4NF 3、 用于数据库恢复的重要文件是C。 A. 数据库文件 B. 备注文件 C. 日志文件...

    达梦数据库_SQL语言手册

    为了有效维护数据库的完整性和一致性,支持 的并发控制机制 语言提供 了事务的回滚( )与提交( )语句。同时允许选择实施事务级读一致 性,它保证同一事务内的可重复读,为此提供用户多种手动上锁语句,和设置事务...

    分布式数据库系统-复习.doc

    原子性 一致性 隔离性 耐久性 控制分布式事务所执行的控制模型有: 、 和 。 主从模型 三角模型 层次模型 分布式数据库系统中,通信故障可以分为 和 两种。 报文故障 网络分割故障 事务恢复主要是依靠 来实现的。 ...

    MySQL事务的四个特征及其隔离级别

    目录1、事务概念2、事务使用3、事务的四大特征(ACID)3.1 原子性(atomicity)3.2 一致性(Consistency)3.3 隔离性(Isolation)3.3.1 read uncommitted(读未提交的);3.3.2 read committed(读已提交的);3.3.3 ...

    MySQL四种事务隔离级别详解

     2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。  3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据

    MySQL的四种事务隔离级别

    2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没收到。3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有...

    [详细完整版]4数据库.txt

    事务是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务:原子性,事务必须是原子工作单元;对于其数据修改,要么...

    最新MySQL高频面试题.rar

    事务特性ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。 一致性是指一个事务执行之前和执行...

    数据库系统概论-SQL-CH10-作业解答.doc

    第十章 数据库恢复技术 1、试述事务的概念及事务的四个特性。恢复技术能保证事务的哪些特性? 答:事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,事务是一 个不可分割的工作单元。 事务具有4个...

Global site tag (gtag.js) - Google Analytics