快捷搜索:
来自 网络数据库 2019-12-01 12:22 的文章
当前位置: 67677新澳门手机版 > 网络数据库 > 正文

中的6种事务隔离级别简单总结,事务隔离级别

 

一、事务隔离级别控制着事务的如下表现:

本文出处: 
(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)

  1. 读取数据时是否占用锁以及所请求的锁类型。
  2. 占用读取锁的时间。
  3. 引用其他事务修改的行的读操作是否:

 

    • 在该行上的排他锁被释放之前阻塞其他事务。
    • 检索在启动语句或事务时存在的行的已提交版本。
    • 读取未提交的数据修改。

数据库中的事物是具有原子性(Atomicity),一致性(Consistemcy),隔离性(Isolation),持久性(Durability)四个特征。
在上述四个特性中的一致性和隔离性的实现中,是通过锁来实现对相同数据的访问隔离的。
新京葡娱乐场网址 ,事物的隔离级别又可以影响锁的申请和时间的时机。
因此,不同的事物隔离级别又可以对锁的申请和释放产生不同的影响,因此,在对数据库做事物控制的时候需要了解隔离级别对事物的影响。
SQL Server实现SQL99标准规定的事务的四个隔离级别(未提交读,已提交读,可重复读,序列化)之外,另外增加了两个隔离级别(快照个基于行版本的已提交读隔离级别)。
不同的隔离级别对控制脏读,不可重复读,幻读有一定的控制,也会并发有一定程度的影响,
隔离级别越低,并发性越高,但是产生脏读,不可重复读,幻读等可能性越大;随着事物隔离级别的提交,可以控制脏读,不可重复读,以及幻读的现象,但是并发性也会随之降低。
事物隔离级别和执行计划都可以影响锁(范围)的申请和释放时机,本文暂不讨论执行计划对锁申请的影响,仅在隔离级别上说明锁的申请和释放。
以下简单介绍SQL Server中的六个隔离级别以及每个隔离级别的特征,在此基础上说明每个隔离级别可能存在的问题解决方法。

以上说明事务隔离级别主要针对读操作来说的。(DML语句我们可以不考虑事务隔离级别,因为任何事物隔离级别下DML的加锁都很严格,属于得不到就等待的类型)

未提交读

二、脏读、不可重复读、幻读的区别:

运行当前Session读取其他事务已修改但是尚未提交的数据,也即当前Session可以读取到“脏数据”。
当前Session不会对读取的数据加共享锁。
set transaction isolation level read uncommitted;
或者
select * from table with(nolock)

提到事物隔离级别就不能不提这3个概念,可以说事务隔离级别就是为了避免这3种情况出现的。

特点:未提交读是最低的一种隔离级别。
存在的问题:脏读,不一致读,幻读等。

脏读:读到了其他事务已修改但未提交的数据

如下是未提交度的存在脏读一种演示(当然也会存在不一致读,幻读等情况)。

不可重复读:由于其他事务的修改,导致同一事务中两次查询读到的数据不同

   新京葡娱乐场网址 1

幻读:由于其他事务的修改,导致同一事务中两次查询读到的记录数不同

 

可能有人对幻读和不可重复读的定义不太理解,两者最大的区别实质上在于加锁的不同,后边会有讲解。

已提交读

三、ANSI/ISO标准定义了下列事务隔离级别,SQL Server数据库引擎支持全部这4种隔离级别:

set transaction isolation level read committed;
或者
select * from table  默认人就是已提交读
运行当前Session不能读取其他事务已修改但是尚未提交的数据。
如果其他事务提对当前Session读取的数据有修改且尚未提交,当前Session被阻塞。
原因是在以已提交读隔离级别情况下:当前Session会对读取的数据加共享锁,如果遇到读取的数据尚未提交,当前查询被阻塞。

新京葡娱乐场网址 2

特点:相比为提交读隔离级别,解决了未提交读隔离级别下的读取“脏数据”的问题,
存在的问题:存在不可重复度或者幻读的问题。

因此四种隔离级别与脏读、幻读、不可重复读的对应情况如下:

 

新京葡娱乐场网址 3

已提交读隔离级别下存在不可重复读的现象(两次读取的同一行数据结果不一致)

需要特别提醒的是:虽然Mysql、Oracle所支持的事务隔离级别也基本遵循ANSI标准,但却有很大区别:

 新京葡娱乐场网址 4

  • Oracle只支持已提交读和序列化读。
  • Mysql默认的的可重复读隔离级别通过范围锁实现了避免幻读。

 

四、除以上4种隔离级别外SQL Server还支持使用行版本控制的其他两个事务隔离级别:

 不可重复读隔离级别下存在的幻读现象(一个事物中,同样的条件,读到的数据行数不一致)

  • 一个是默认的read committed隔离级别下的snapshot实现,严格来说并不算一个事务隔离级别,只是read committed的一个特殊形态。

   新京葡娱乐场网址 5

  • 一个是全新的事务隔离级别----快照隔离级别。

 

两者的开启方式为:

可重复读

1、如果要开启SNAPSHOT事务隔离级别,需要预先设置ALLOW_SNAPSHOT_ISOLATION为ON,且目前只能修改会话级别的事务隔离级别。

set transaction isolation level repeatable read;
运行当前Session不能读取其他事务已修改但是尚未提交的数据,并且当前Session运行期间,其他Session不能修改当前Session读取到的数据
也就是说,当前Session运行期间,读取到的数据是被加了共享锁的,所加的共享锁一直保持,直到事务提交的时候才释放。
相比已提交读最大的特点就是事务运行期间,共享锁将一直保持,直到当前Session事务提交,
因此可以保持当前Session读取到的数据不被其他Session修改,所以就不存在两次读取的数据不一致的现象。
可重复读隔离级别解决了不可重复读的问题,但依旧存在幻读的情况。

ALTER DATABASE [dbname] SET ALLOW_SNAPSHOT_ISOLATION ON; --需要单用户模式下修改,因为要加库级别的独占锁。

 然后执行如下语句修改事务隔离级别:(修改后只在会话级别生效,无法修改全局级别的事务隔离级别)

SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
}

特点:相比前一种隔离级别,可重复读解决了已提交读隔离级别的不可重复读的问题,也即两次读取的同一行数据是一致的
存在的问题:相比已提交读,依旧存在幻读的问题。

2、使用READ_COMMITTED_SNAPSHOT,则直接执行下列ALTER语句修改,是在默认的READ COMMITTED隔离级别下修改的,此隔离级别修改后永久生效,使用dbcc useroptions查看可以看到事务隔离级别被全局的修改成了read committed snapshot。

 

ALTER DATABASE [dbname] SET READ_COMMITTED_SNAPSHOT ON;

  如下是可重复读隔离级别的幻读的现象,也即在同一个事物的两次读取期间,其他事物可以写入当前事物读取的数据(范围)

两者的区别在于:

  新京葡娱乐场网址 6

READ_COMMITTED_SNAPSHOT是指Select语句总是读取最新的已提交的数据,即如果有DML事务正在执行,那么select语句不会被阻塞而是读取这些DML事务预先生成的前镜像,这种读只会在表上加Sch-S锁,其他的行锁页锁全部没有。DML数据一旦提交,再次执行Select语句就会立马读到新的数据。

可序列化

SNAPSHOT隔离级别与上述的区别在于,如果你在同一个事务内执行两次相同的select语句,那么即便在这两次select语句之间发生了数据更改且提交,两次读到的数据也是一样的。

当前Session不能读取其他Session已修改但未提交的数据(不允许脏读)
当前Session读取的数据上的共享锁一直保持直到事务提交(可重复读)
当前Session事务提交之前,其他Session不能插入当前Session中读取的键值(解决了幻读的问题)
set transaction isolation level serializable
或者开启事务之后对表加holdlock提示
select * from table with(holdlock) where id = n
可序列化解决了另外一个非常经典的问题,使用update table with(holdlock) 或者select * from table with(xlock,holdlock),并发情况下的“存在则更新不存在则插入”重复插入的问题。
参考:

用官网的一句话来描述两者区别就是:READ_COMMITTED_SNAPSHOT提供语句级的一致性,SNAPSHOT事务隔离级别提供事务级的一致性。

可序列化锁定的原理是加范围锁的方式来实现的,当一个Session发起了请求之后,对于当前Session范围内的数据,不管是否存在,都加一个共享锁。
比如在可序列化的隔离级别之下,select * from table with where id>=100 and id<= 120
在Session执行期间,SQL Server会锁定 100<=id<= 120这个范围的数据,不管表中这个区间是否存在数据, 都锁定这个Id的范围,不允许该Id范围的数据写入。
也即100<=id<= 120这个范围被所锁定(无法增加删除或者修改这个范围的数据)

五、全部6种隔离级别的加锁模式:

 

开始说过事务隔离级别主要就是控制读操作加什么锁,锁占用多长时间的的,因此只有搞清各事务隔离级别下的加锁机制才能彻底搞清事务隔离级别的概念和他们的不同。

可序列化隔离级别解决了幻读的问题,也就是说,当前事物的两次读中间,其他Session对当前Session读取数据范围之内的数据修改的时候,会被阻塞,直到当前事物提交。

1.未提交读

本文由67677新澳门手机版发布于网络数据库,转载请注明出处:中的6种事务隔离级别简单总结,事务隔离级别

关键词: