电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

SQLSERVER 的四个事务隔离级别到底怎么理解?

来源:金蝶云社区作者:金蝶2024-09-162

SQLSERVER 的四个事务隔离级别到底怎么理解?

SQLSERVER 的四个事务隔离级别到底怎么理解? 

一:背景

1. 讲故事

在有关SQLSERVER的各种参考资料中,经常会看到如下四种事务隔离级别。

  • READ UNCOMMITTED

  • READ COMMITTED

  • SERIALIZABLE

  • REPEATABLE READ

随之而来的是大量的文字解释,还会附带各种 脏读幻读不可重复读 常常会把初学者弄得晕头转向,其实事务的本质就是隔离,落地就需要锁机制,理解这四种隔离方式的花式加锁,应该就可以入门了,那如何可视化的观察  过程呢?这里借助 SQL Profile 工具。

二:四种事务隔离方式

1. 测试数据准备

还是用上一篇创建的 post 表,脚本如下:

CREATE TABLE post(id INT IDENTITY,content char(4000))
GOINSERT INTO dbo.post VALUES('aaa')INSERT INTO dbo.post VALUES('bbb')INSERT INTO dbo.post VALUES('ccc');INSERT INTO dbo.post VALUES('ddd');INSERT INTO dbo.post VALUES('eee');INSERT INTO dbo.post VALUES('fff');

有了测试数据之后,我们按照隔离级别 高 -> 低 的顺序来观察吧。

2. SERIALIZABLE 事务

事务串行化 其实很好理解,如果要在 C# 中找对应那就是 ReaderWriterLock,读写事务是完全排斥的,接下来把 SQLSERVER 的隔离级别调整为 SERIALIZABLE

SET TRAN ISOLATION LEVEL SERIALIZABLE
GOBEGIN TRAN 
SELECT * FROM dbo.post WHERE id=3COMMIT

打开 profile,选择 lock:Acquired, lock:Released,SQL:StmtStarting 选项,开启观察。

从图中可以清楚的看到,SQLSERVER 直接对 post 附加了 S 锁,在 COMMIT 之后才真正的释放,在 S 锁期间, Insert 和 Update 引发的 X 锁是进不来的,所以就会存在相互阻塞的情况,也许这就是串行化的由来吧。

sqlserver 是一个支持多用户并发的数据库程序,如果锁粒度这么粗,必定给并发带来非常大的负面影响,不过文章开头的那三个指标 脏读, 幻读, 不可重复读 肯定都是不会出现的。

2. REPEATABLE READ 事务

什么叫 可重复读 呢?简而言之就是同一个 select 查询执行二次,不会出现记录修改的情况,在真实场景中两次 select 查询期间,可能会有其他事务修改了记录,如果当前是 REPEATABLE READ 模式,这是被禁止的,接下来的问题是如何落地实现呢?我们来看看 SQLSERVER 是如何做到的,参考sql 如下:

SET TRAN ISOLATION LEVEL REPEATABLE READ
GOBEGIN TRAN 
SELECT * FROM dbo.post WHERE id=3COMMIT

这个图可能有些朋友看不懂,我稍微解释一下吧,数据库由数据页Page组成,数据页由记录RID 组成,有了这个基础就好理解了, SQLSERVER 会在事务期间把 1:489:0 也就是 id=3 这个记录全程附加 S 锁,直到事务提交才释放 S 锁,在事务期间任何对它修改的 X 锁都无法对其变更,从而实现事务期间的 可重复读 功能,如果大家不明白可以再琢磨琢磨。

这里有一个细节需要大家注意一下,可重复读 的场景下会出现 幻读 的情况,幻读就是两次查询出的结果集可能会不一样,比如第一次是 3 条记录,第二次变成了 5 条记录,为了方便理解我来简单演示一下。

  • 会话1

SET TRAN ISOLATION LEVEL REPEATABLE READ
GOBEGIN TRAN 
SELECT * FROM dbo.post WHERE id >3WAITFOR DELAY '00:00:05'SELECT * FROM dbo.post WHERE id >3COMMIT
  • 会话2

会话1 执行的 5s 期间执行 会话2 语句。

BEGIN TRAN 
INSERT INTO dbo.post(content) VALUES ('gggggg')COMMIT

稍等片刻之后,会发现多了一个 记录

SQLSERVER 的四个事务隔离级别到底怎么理解?

随笔 - 479 文章 - 0 评论 - 7338 阅读 - 533万SQLSERVER 的四个事务隔离级别到底怎么理解? 一:背景1. 讲故事在有关SQLSERVE...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

已经是第一篇
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信