五、锁与事务隔离级别

事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误。设置事务隔离级别将影响整条连接。

SQL Server 数据库引擎支持所有这些隔离级别:

· 未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据)

· 已提交读(数据库引擎的默认级别)

· 可重复读

· 可序列化(隔离事务的最高级别,事务之间完全隔离)

SQL Server 还支持使用行版本控制的两个事务隔离级别。一个是已提交读隔离的新实现,另一个是新事务隔离级别(快照)。

设置语句如下:

SET TRANSACTION ISOLATION LEVEL

{ READ UNCOMMITTED

| READ COMMITTED

| REPEATABLE READ

| SNAPSHOT

| SERIALIZABLE

}

[ ; ]

(一)未提交读

未提交读是最低的事务隔离级别,允许读取其他事务已经修改但未提交的数据行。SQL SERVER 当此事务等级进行尝试读取数据时,不会放置共享锁,直接读取数据,所以忽略已存在的互斥锁。换句话说,即使该资源已经受到了独占锁的保护,当使用未提交读隔离级别时,此数据还是可以被读取,加快查询速度,但是会读取到别人未修改的数据,所以此种读取被称为脏读。此种隔离级别适合不在乎数据变更的查询场景。此隔离级别与SELECT 语句搭配 NOLOCK 所起到的效果相同

未提交读示例:

--1.--1.创建测试表

create table tbUnRead

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbUnRead

select 1,'Tom'

union

select 2,'Jack'

--3开启事务,并进行更新

begin tran

update tbUnRead

set name='Jack_upd'

where ID=2

---4查询事务数量(由于没有回滚或提交事务)

SELECT @@TRANCOUNT

事务查询结果如下:

--5打开另一条连接,设置事务隔离级别为(未提交读)

set Transaction isolation level read uncommitted

--6查询数据,查询到的数据是修改之后的数据。

select * from tbUnRead where ID=2

如下图:

(二)已提交读

已提交读是SQL SERVER 默认的事务隔离级别。当事务正在读取数据时,SQL SERVER 会放置共享锁以防止其他事务修改数据,当数据读取完成之后,会自动释放共享锁,其他事务可以进行数据修改。因为共享锁会同时封锁封锁语句执行,所以在事务完成数据修改之前,是无法读取该事务正在修改的数据行。因此此隔离级别可以防止脏读。

在SQL SERVER 2005以上版本中,如果设置READ_COMMITTED_SNAPSHOT为ON,则已提交读的事务全使用数据行版本控制的隔离下读取数据。读取操作不会获取正被读取的数据上的共享锁(S 锁),因此不会阻塞正在修改数据的事务。同时,由于减少了所获取的锁的数量,因此最大程度地降低了锁定资源的开销。使用行版本控制的已提交读隔离和快照隔离旨在提供副本数据的语句级或事务级读取一致性。

示例一:设置READ_COMMITTED_SNAPSHOT为OFF

--1.创建测试表

create table tbUnRead

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbUnRead

select 1,'Tom'

union

select 2,'Jack'

--3开启事务,并进行更新

begin tran

update tbUnRead

set name='Jack_upd'

where ID=2

---4查询事务数量(由于没有回滚或提交事务)

SELECT @@TRANCOUNT

--5打开另一条连接,设置事务隔离级别为(已提交读)

set Transaction isolation level read committed

--6查询数据,由于当前事务没有提交,所以无法查询数据

select * from tbUnRead where ID=2

6查询数据的结果 如下图:

示例二:设置READ_COMMITTED_SNAPSHOT为ON

use master

go

---创建测试数据库

create database read_committed_SNAPSHOT_Test

go

---激活数据行版本控制

alter database read_committed_SNAPSHOT_Test  set read_committed_SNAPSHOT on

go

use read_committed_SNAPSHOT_Test

go

--1.创建测试表

create table tbReadLevel

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbReadLevel

select 1,'测试'

go

select ID,name as "修改前数据"  from tbReadLevel

如下图:

go

--3开启事务,并进行更新

begin tran

update tbReadLevel

set name='Jack_upd'

where ID=1

---4查询事务数量(由于没有回滚或提交事务)

SELECT @@TRANCOUNT

--5打开另一条连接,设置事务隔离级别为(已提交读)

--查询数据,查询到的数据是上一次提交的数据

select * from tbReadLevel where ID=1

5的查询结果如下图:

(三)可重复读

可重复读事务隔离级别在事务过程中,所有的共享锁均保留到事务结束,而不是读取结束就释放,这与已提交读的行为截然不同,虽然在事务过程中,重复查询相同记录时不受其他事务的影响,但可能由于锁定数据过久,而导致其他人无法处理数据,影响并发率,更严重的可能提高发生死锁的机率。

总之,如果使用可重复读隔离级别读取数据,数据读出之后,其他事务只能对此范围中的数据进行读取或新增,但不可以进行修改,直到读取事务完成。因此,使用此隔离级别需要谨慎小心,根据实际情况进行设置。

示例:

--1.创建测试表

create table tbUnRead

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbUnRead

select 1,'Tom'

union

select 2,'Jack'

--3设置事务隔离级别为(可重复读)

set Transaction isolation level REPEATABLE READ

--4开启事务,并进行更新

begin tran

--5查询数据

select * from tbUnRead where ID=2

---6查询事务数量(没有回滚或提交事务)

SELECT @@TRANCOUNT

5与6的执行结果如下图

---7开启另一条连接,查询数据与修改数据

---事务虽然没有完成,但可以查询到之前的数据

select * from tbUnRead where ID=2

Go

---8,修改数据,由于事务没有完成,所以无法进行修改

update tbUnRead

set name='Jack_upd'

where ID=2

go

--7、8的执行结果如下,可以查询数据,但无法更新数据,如下图。

(四)快照

快照隔离级别是SQL SERVER 2005之后版本新增的隔离级别,开启之后,允许事务过程中读取操作不受异动影响,事务中任一语句所读取的数据,均予事务激活时,就已经完成提交,符合事务一致性的数据行版本。所以只能查核事务激活之前已经完成提交的数据,也就是说可以查询已经完成提交的数据行快照集,但看不见已激活的事务正在进行修改的数据行。当使用快照隔离级别读取数据时不会要求对数据进行锁定,如果所读取的记录正在被某事务进行修改,它也会读取此记录之前已经提交的数据。故当某记录被事务进行修改时,SQL SERVER的TEMPDB数据库会存储最近提交的数据行,以供快照隔离级别的事务读取数据时使用。将Allow_SNAPSHOT_isolation设为ON,事务就会设置快照隔离级别。

use master

go

---创建测试数据库(快照)

create database SNAPSHOT_Test

go

---激活数据行版本控制

alter database SNAPSHOT_Test  set Allow_SNAPSHOT_isolation on

go

use SNAPSHOT_Test

go

--1.创建测试表

create table tbReadLevel

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbReadLevel

select 1,'测试'

union

select 2,'快照测试'

go

select ID,name as "修改前数据"

from tbReadLevel

go

--3开启事务,并进行更新

begin tran

update tbReadLevel

set name='Jack_upd_快照'

where ID=1

---4查询事务数量(没有回滚或提交事务)

SELECT @@TRANCOUNT

--2、4的执行结果,如下图。

--5打开另一条连接,设置事务隔离级别为(快照)

set Transaction isolation level SNAPSHOT

--6查询数据,查询的数据是上一次提交的数据

select * from tbReadLevel where ID=1

(五)可序列化

可序列化是事务隔离级别中最高的级别,为最严谨的隔离级别,因为它会锁定整个范围的索引键,使事务与其他事务完全隔离。在现行事务完成之前,其他事务不能插入新的数据行,其索引键值存在于现行事务所读取的索引键范围之中。此隔离级别与Select 搭配holdlock效果一样。

示例:

--1.创建测试表

create table tbUnRead

(ID INT,

name nvarchar(20)

)

--2新增记录

insert tbUnRead

select 1,'Tom'

union

select 2,'Jack'

--3设置事务隔离级别为(可序列化)

set Transaction isolation level SERIALIZABLE

--5开启事务,并进行更新

begin tran

select * from tbUnRead where ID=2

---6查询事务数量(没有回滚或提交事务)

SELECT @@TRANCOUNT

5、6执行结果如下图。

---7,开启另一条连接,查询数据,可以查询到之前的数据

select * from tbUnRead where ID=2

---8,修改数据,无法修改数据

update tbUnRead

set name='Jack_upd'

where ID=2

--新增数据,无法插入数据

insert tbUnRead

select 3,'May'

(转)SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)的更多相关文章

  1. (转)SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)

    六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...

  2. Innodb中的事务隔离级别和锁的关系

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力. ...

  3. Innodb中的事务隔离级别和锁的关系(转)

    原文:http://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库 ...

  4. sql server对并发的处理-乐观锁和悲观锁

    https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...

  5. 在SQL Server里为什么我们需要更新锁

    今天我想讲解一个特别的问题,在我每次讲解SQL Server里的锁和阻塞(Locking & Blocking)都会碰到的问题:在SQL Server里,为什么我们需要更新锁?在我们讲解具体需 ...

  6. 【转】SQL Server 2012 配置AlwaysOn(三)

    转载自:http://www.cnblogs.com/lyhabc/p/4682986.html 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http:/ ...

  7. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  8. SQL Server 事务隔离级别详解

    标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设置数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一 ...

  9. SQL Server 之 事务隔离级别

    SET TRANSACTION ISOLATION LEVEL xxx  -- 每次设置只针对当前事务块 xxx 取值: READ UNCOMMITTED READ COMMITTED REPEATA ...

随机推荐

  1. coreseek 安装及使用方法详解

    coreseek 安装及使用 一般站点都需要搜索功能,如果是php+mysql站点,建议选择coreseek,如果是java站点建议使用lucene,coreseek 是一款很好的中文全文检索/搜索软 ...

  2. JS判断网页是否在微信中打开/

    JS判断网页是否在微信中打开,代码如下: <script type="text/javascript"> function is_weixn(){ var ua = n ...

  3. JavaScript判断各浏览器CSS前缀的两种方式

    不管浏览器更新的多快,号称多么支持标准.厂商不同,他们之间还是有很多差异.我们需要区分出这些差异,针对不同的浏览器做不同的处理. 比如 CSS 前缀,IE 的是 "-ms-",旧版 ...

  4. JDBC三层架构

    三层框架: 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI).业务逻辑层(BLL).数据访问层(DAL).区分层次的目的即为了“高内聚,低耦合”的思想. 原理:1:数据访问层:主要是对原始 ...

  5. ROS学习笔记(三)——ROS安装

    安装指南: indigo安装 http://wiki.ros.org/indigo/Installation/Ubuntu 中文参考教程: http://wiki.ros.org/cn 1.配置Uba ...

  6. javascript Windouw 转自 http://www.cnblogs.com/kissdodog/archive/2013/01/01/2841464.html

    javascript之window对象 window :window对象是BOM中所有对象的核心,除了是BOM中所有对象的父对象外,还包含一些窗口控制函数. 1.全局的window对象 JavaScr ...

  7. TCP的关闭,到底是几次握手,每次的标志位到底是什么!

    做题的时候遇到一个问题,TCP关闭的时候到底是三次还是四次握手,如果是三次,少了哪部分?   按照 <计算机网络> -第五版-谢希仁       然而对于TCP关闭, 有的地方能找到   ...

  8. Mybatis根据表自动生成相关代码

    这个地方的生成需要用到三个文件,generatorConfig.xml.mybatis-generator-core-1.3.1.jar和mysql-connector-java-5.1.29.jar ...

  9. ssh搭建后的简化

    关于ssh如何搭建还有不懂得朋友可以参考以下网址:http://www.cnblogs.com/LarryBlogger/p/5841446.html 在这里我就不重复再讲了! ssh搭建后的简化 简 ...

  10. Go Deeper(2010成都现场赛题)(2-sat)

    G - Go Deeper Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description ...