前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SQL Server中锁与事务隔离级别

SQL Server中锁与事务隔离级别

作者头像
雪飞鸿
修改于 2018-11-15 06:29:49
修改于 2018-11-15 06:29:49
1.5K0
举报
文章被收录于专栏:me的随笔me的随笔

SQL Server中的锁分为两类:

  • 共享锁
  • 排它锁

锁的兼容性:事务间锁的相互影响称为锁的兼容性。

锁模式

是否可以持有排它锁

是否可以持有共享锁

已持有排它锁

已持有共享锁

SQL Server中可以锁定的资源包括:RID或键(行)、页、对象(如表)、数据库等等。

在试图修改数据(增删改)时,事务会请求数据资源的一个排它锁而不考虑事务的隔离级别。排它锁直到事务结束才会解除。对于单语句事务,语句执行完毕该事物就结束了;对于多语句事务,执行完COMMIT TRAN或者ROLLBACK TRAN命令才意味着事务的结束。

在事务持有排它锁期间,其它事务不能修改该事物正在操作的数据行,但能否读取这些行,则取决于事务的隔离级别。

在试图读取数据时,事务默认请求数据资源的共享锁,事务结束时会释放锁。可以通过事务隔离级别控制事务读取数据时锁定的处理方式。


SQL Server中事务隔离级别分为以下两大类:

  • 基于悲观并发控制的四个隔离级别(隔离级别自上而下依此增强):
代码语言:txt
AI代码解释
复制
- READ UNCOMMITTED
- READ COMMITTED(默认)
- REPEATABLE READ
- SERIALIZABLE基于乐观并发控制的两个隔离级别(隔离级别自上而下依此增强):
代码语言:txt
AI代码解释
复制
- SNAPSHOT
- READ COMMITTED SNAPSHOT(默认)

可以通过下面的语句来设置会话的隔离级别:

代码语言:txt
AI代码解释
复制
SET TRANSACTION ISOLATION LEVEL <isolation name>

隔离级别可以确定并发用户读取或写入的行为。在获得锁和锁的持续期间,不能控制写入者的行为方式,当时可以控制读取者的行为方式。此外,也可通过控制读取者的行为方式来隐式的影响写入者的行为。隔离级别越高读取者请求的锁越强,持续时间越长,数据一致性越高,并发性越低。

READ COMMITTED SNAPSHOTSNAPSHOT可以看作是READ COMMITTEDSERIALIZABLE对应的乐观并发控制实现。

在事务持有一个数据资源的锁时,若另一个事务请求该资源的不兼容锁时,请求会被阻塞而进入等待状态。该请求一直等待直至被锁定的资源释放或者等待超时。可以通过语句以下语句来查询数据库中事务锁信息:

代码语言:txt
AI代码解释
复制
--获取当前会话Id
SELECT @@SPID;
--查询数据库中锁信息
SELECT * FROM sys.dm_tran_locks;
--使用KILL命令关闭id为52的会话
--注意KILL命令不是SQL而是SQL Server用于管理数据库的命令
--KILL命令会回滚事务
KILL 52;

设置锁超时时间,锁超时不会回滚事务:

代码语言:txt
AI代码解释
复制
--设置锁超时时间为5S
SET LOCK_TIMEOUT 5000;
--取消超时时间限制
SET LOCK_TIMEOUT -1;

READ UNCOMMITTED

在该隔离级别中,读取者无需请求共享锁,从而也不会与持有排它锁的写入者发生冲突。如此,读取者可以读到写入者尚未提交的更改。即,脏读。

在查询语句中READ COMMITTED可以简写为NOLOCK

代码语言:txt
AI代码解释
复制
SELECT * FROM A WITH(NOLOCK)

READ COMMITTED

在该隔离级别中,读取者必须获取一个共享锁以防止读取到未提交的数据。这意味着,若有其它事务正在修改资源则读取者必须进行等待,当写入者提交事务后,读取者就可以获得共享锁进行读取。

该隔离级别中,事务所持有的共享锁不会持续到事务结束,当查询语句结束(甚至未结束)时,便释放锁。这意味着在同一个事物中,两次相同数据资源的读取之间,不会持有该资源的锁,因此,其它事务可以在两次读取间隙修改资源从而导致两次读取结果不一致,即不可重复读,同时该隔离级别下也会产生更新丢失问题。

REPEATABLE READ

在该隔离级别中,读取者必须获取共享锁且持续到事务结束。该隔离级别获得的共享锁只会锁定执行查询语句时符合查询条件的资源。举例如下:

代码语言:txt
AI代码解释
复制
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT * FROM A WHERE Id<10;

上述语句只会锁定符合Id<10条件的数据行,若表中Id<10的数据有Id=2,3,4,5,6五条,那么只会锁定这五条数据:

代码语言:txt
AI代码解释
复制
--阻塞
DELETE FROM A WHERE Id=2;
--不会阻塞
DELETE FROM A WHERE Id=7;
--阻塞
UPDATE A SET Name='' WHERE Id=2;
--不会阻塞
UPDATE A SET Name='' WHERE Id=7;
--不会阻塞,且新插入的数据不会被锁定,可以执行更新和删除操作
INSERT INTO A(Id,Name) VALUES(7,'5');

该隔离级别下可以避免更新丢失问题,但会产生幻读,即同一事务两次相同条件的查询之间插入了新数据,导致第二次查询获取到了新的数据。

SERIALIZABLE

在该隔离级别中,读取者必须获取共享锁且持续到事务结束。该隔离级别的共享锁不仅锁定执行查询语句时符合查询条件的数据行,也会锁定将来可能用到的数据行。即,阻止可能对当前读取结果产生影响的所有操作。

举例如下:

代码语言:txt
AI代码解释
复制
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM A WHERE Id<10;

上述语句只会锁定符合Id<10条件的数据行,若表中Id<10的数据有Id=2,3,4,5,6五条,则:

代码语言:txt
AI代码解释
复制
--阻塞
DELETE FROM A WHERE Id=2;
--不会阻塞
DELETE FROM A WHERE Id=7;
--阻塞
UPDATE A SET Name='' WHERE Id=2;
--不会阻塞
UPDATE A SET Name='' WHERE Id=7;
--阻塞,这里与 REPEATABLE READ 不一样
INSERT INTO A(Id,Name) VALUES(7,'5');

SNAPSHOTREAED COMMITTED SNPSHOT是SQL Server基于行版本控制技术的隔离级别,在这两个隔离级别中,读取者不会获取共享锁。SQL Server可以在tempdb库中存储已提交行的之前版本。如果当前版本不是读取者所希望的版本,那么SQL Server会提供一个较旧的版本。

SNAPSHOT在逻辑上与SERIALIZABLE类似;READ COMMITTED SNPSHOT在逻辑上与READ COMMITTED类似。这两个隔离级别中执行DELETEUPDATE语句需要复制行的版本,INSERT语句则不需要。因此,对于更新和删除操作的性能会有负面影响,因无需获取共享锁,所以读取者的性能通常会有所改善。

SNAPSHOT

在该隔离级别中,读取者在读取数据时,它是确保获得事务启动时最近提交的可用行版本。这意味着,保证获得的是提交后的读取并且可以重复读取,以及确保获得的不是幻读,就像是在SERIALIZABLE级别中一样。但该隔离级别并不会获取共享锁。

启用该隔离级别需要先执行下面的语句:

代码语言:txt
AI代码解释
复制
--需要在数据库级别启用基于快照的隔离级别
ALTER DATABASE DbName SET ALLOW_SNAPSHOT_ISOLATION ON;  
代码语言:txt
AI代码解释
复制
--修改数据不提交事务
BEGIN TRAN
  UPDATE A SET Name='22' WHERE Id=2;
代码语言:txt
复制
代码语言:txt
AI代码解释
复制
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
--查询不会被阻塞
--上述事务提交之前返回可用的旧版本,提交后则返回修改后的结果
SELECT * FROM xfh.[Table] WHERE Id=2;

冲突检测

该隔离级别的事务中,SQL Server会进行冲突检测以防止更新冲突,这里的检测不会引起死锁问题。即,若该隔离级别的事务在修改数据时,若发现已有其它事务修改了相同版本号的数据,则会引发下面的错误:

代码语言:txt
AI代码解释
复制
消息 3960,级别 16,状态 2,第 4 行
快照隔离事务由于更新冲突而中止。您无法在数据库'Test'中使用快照隔离来直接或间接访问表 'A',
以便更新、删除或插入已由其他事务修改或删除的行。请重试该事务或更改 update/delete 语句的隔离级别。

READ COMMITTED SNPSHOT

该隔离级别与SNAPSHOT的不同之处在于,读取者获得是语句启动时(不是事务启动时)可用的最后提交的行版本。

启用该隔离级别需要先执行下面的语句:

代码语言:txt
AI代码解释
复制
--需要在数据库级别启用基于快照的隔离级别
--要保证执行该语句的链接必须是目标数据库的唯一链接
ALTER DATABASE Test SET READ_COMMITTED_SNAPSHOT ON;

隔离级别

允许脏读?

允许不可重复读?

允许丢失更新?

允许幻读?

检测更新冲突?

使用行版本控制?

READ UNCOMMITTED

READ COMMITTED

REPEATABLE READ

SERIALIZABLE

SNAPSHOT

READ COMMITTED SNAPSHOT

死锁

对于死锁,SQL Server会自行清理。默认情况下,SQL Server会选择终止工作量少的事务以解除死锁,因为工作量少便于事务的回滚操作。用户也可以设置死锁优先级DEADLOCK_PRIORITY,这样优先级低的便被终止,而不管其工作量大小。

结语

SQL Server中提供了四种不依赖行版本控制的事务隔离级别,及两种依赖行版本控制的事务隔离级别。不同事务的隔离级别会对数据查询语句的执行过程(是否获取共享锁,语句是否会被阻塞)及结果(是否有脏读、幻读等)产生较大的影响,对于修改数据行为的影响仅限于是否会阻塞语句的执行,因为修改数据的语句必须要获取排它锁才能被执行。

以上是自己《SQL Server2012 T-SQL基础教程》事务与并发处理一章的读书笔记,错误之处望各位多多指教。

推荐阅读

数据库村的旺财和小强

sql server锁知识及锁应用

数据库两大神器【索引和锁】

SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

漫话:MySQL中的行级锁,表级锁,页级锁

书目推荐

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Python | Python 新手不可错过的 Python 知识合集
来源:https://segmentfault.com/a/1190000018737045
咸鱼学Python
2020/04/08
1.5K0
万字长文Python面试题,年后找工作就靠这了
编译型语言:把做好的源程序全部编译成二进制的可运行程序。然后,可直接运行这个程序。如:C,C++
周萝卜
2021/02/25
5260
万字长文Python面试题,年后找工作就靠这了
精心整理170道Python面试题,建议先收藏
精心整理的 Python 相关的基础知识,用于面试,或者平时复习,都是很好的!废话不多说,直接开搞
周萝卜
2022/05/22
6620
精心整理170道Python面试题,建议先收藏
web端rtmp推拉流测试、抽帧识别计数,一键式生成巡检报告
本文旨在实现无人机城市交通智慧巡检中的一个模块——无人机视频实时推拉流以及识别流并在前端展示,同时,统计目标数量以及违停数量,生成结果评估,一并发送到前端展示。对于本文任何技术上的空缺,可在博主主页前面博客寻找,
用户11404404
2025/06/08
700
Python多线程与多进程详解:性能提升技巧与实战案例
文章链接:https://cloud.tencent.com/developer/article/2464989
一键难忘
2024/11/12
6540
Python多线程与多进程详解:性能提升技巧与实战案例
Python异步IO操作,看这个就够了
异步 IO 是一种并发编程设计,Python3.4 开始,已经有专门的标准库 asyncio 来支持异步 IO 操作。你可能会说,我知道并发用多线程,并行用多进程,这里面的知识已经够我掌握的了,异步 IO 又是个什么鬼?本文将会回答该问题,从而使你更加牢固地掌握 Python 的异步 IO 操作方法。
somenzz
2020/11/25
2.9K0
Python异步IO操作,看这个就够了
软件测试面试中都会问到哪些关于Python的问题?
答:Python是一门语法简洁优美, 功能强大无比, 应用领域非常广泛, 具有强大完备的第三方库,它是一门强类型的可移植、可扩展、可嵌入的解释型编程语言,属于动态语言。
霍格沃兹测试开发
2020/12/17
7810
python核心知识汇总(精编版)
你好啊,我是阿巩。转眼已连续更新一周了,可咱毕竟是讲Python的公众号,不来点Python基础干货就有些说不过去,就像茶馆里没有茶、犬舍里没有狗子、老婆饼里没有老婆(都什么乱七八糟的比喻?!)之前有写过篇万字长文,今天来根据面试常问的内容整理下,做个精编版。日拱一卒,让我们开始吧!
才浅Coding攻略
2022/12/12
1.5K0
Python面试题大全(一):基础知识学习
目录 Python基础 文件操作 1.有一个jsonline格式的文件file.txt大小约为10K 2.补充缺失的代码 模块与包 3.输入日期, 判断这一天是这一年的第几天? 4.打乱一个排好序的l
不吃西红柿
2022/07/29
7300
面试题目及答案
1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun(a) print a # [1] 所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。 通过id来看引用a的内存地址可以比较理解: a = 1 def fun(a): print "func_in",id(a) # func_in 413224
zhang_derek
2018/04/11
4.4K0
面试题目及答案
python多线程
1 多进程 # 多进程, import os import time from multiprocessing import Process # 启动时必须在 if __name__ 判断下,windows 必须,其他 无限制 # ================================================= # def func(args): # print("子进程:",os.getpid()) # print("子进程的父进程:",os.getppid()) #
Dean0731
2020/05/08
1.7K0
Python协程-asyncio、async/await
上面的代码也可以这样写,将15到21行换成一行await asyncio.gather(a(), b())也能实现类似的效果,await asyncio.gather 会并发运行传入的可等待对象(Coroutine、Task、Future)。
Cloud-Cloudys
2020/07/07
3.3K0
暑假爆肝整理这篇python基础教程,全是干货,学完基础就过关(收藏加好评吧)
本基础分为十个部分: 1-数字 2-字符串 3-列表 4-控制流 5-函数 6-数据结构 7-模块 8-深层输入与输出 9-异常和错误 10-类 11-标准库简介 12-协程
川川菜鸟
2021/10/18
6010
Python学习(十)---- python中的进程与协程
原文地址: https://blog.csdn.net/fgf00/article/details/52790360 编辑:智能算法,欢迎关注! 上期我们一起学习了python中的线程的相关知识
智能算法
2018/10/08
5560
Python进阶篇
大家好,我是易安!今天我们继续Python的学习,内容稍微有些多,不过我会尽可能举一些例子让你理解。
架构狂人
2023/08/16
1.1K0
Python进阶篇
Python基础知识总结(期末复习精简版)「建议收藏」
本文针对《Python语言程序设计基础 (第2版)》——嵩天 礼欣 黄天羽,此书进行简单知识总结。
全栈程序员站长
2022/09/06
2K0
Python基础知识总结(期末复习精简版)「建议收藏」
2019 Python 面试 100 问,你会几道?
1.通过headers反爬虫 2.基于用户行为的发爬虫:(同一IP短时间内访问的频率) 3.动态网页反爬虫(通过ajax请求数据,或者通过JavaScript生成) 4.对部分数据进行加密处理的(数据是乱码)
AI算法与图像处理
2019/06/03
1.2K0
Python 面试题大全系列(二)
如:("zhangfei", "guanyu"),(66, 80) -> {'zhangfei': 66, 'guanyu': 80}
周萝卜
2019/07/17
1.1K0
Python 面试题大全系列(二)
python协程
https://docs.python.org/zh-cn/3/library/asyncio.html
润森
2019/11/10
5200
[源码分析] 分布式任务队列 Celery 之 发送Task & AMQP
Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。
罗西的思考
2021/04/22
4.1K0
推荐阅读
相关推荐
Python | Python 新手不可错过的 Python 知识合集
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档