设为首页 加入收藏

TOP

SQLServer事务隔离级别的选择如何影响锁定机制(一)
2018-06-12 08:43:17 】 浏览:337
Tags:SQLServer 事务 隔离 级别 选择 如何 影响 锁定 机制

事务隔离级别

最近我在SQLServer Cub上发布了锁定、阻止和死锁的文章。本文将继续讨论事务隔离级别,以及事务隔离级别的选择如何影响先前文中所讨论的锁定机制。

如果我们查看数据库引擎中的联机(BOL)主题隔离级别,可以看到事务隔离级别控制:

在读取数据时是否锁定,以及请求什么类型的锁。

读取锁保持多长时间。

是否引用另一个事务修改的行的读取操作:

块,直到释放行上的排他锁。

检索语句或事务启动时存在的行的提交版本。

读取未提交的数据修改。

注意,这些都只影响数据的读取。在写入数据时获取的锁不受影响——这些仍然需要保护数据修改。事务隔离级别控制读取操作如何免受其他(写入)操作的影响。

SO隔离级别

下表显示了不同的ISO隔离级别,以及它们的并发性副作用:

Isolation Level

Dirty Reads

Nonrepeatable Reads

Phantom Reads

Missing / Double Reads

Read uncommitted

Yes

Yes

Yes

Yes

Read committed

No

Yes

Yes

Yes

Repeatable Read

No

No

Yes

No

Serializable

No

No

No

No

在检查此表时,我们可以看到不同的事务隔离级别被设计为消除并发效应。

SQL Server 2005添加了两个额外的事务隔离级别,它们都涉及利用快照:

Isolation Level

Dirty Reads

Nonrepeatable Reads

Phantom Reads

Missing / Double Reads

Read committed snapshot

No

No

No

No

Snapshot

No

No

No

No

Read SypReType快照是一个数据库级设置,如果它被打开并且事务隔离级别被读取,那么它将使用行版本控制在语句开始时呈现一个事务一致的数据视图。

快照隔离级别还利用行版本控制在语句开始时呈现数据的事务一致视图。这要求打开AsvixSnAsHOTHOTION数据库设置,并为查询发出SET事务隔离级别快照语句。

在这两种快照隔离级别中,效果是读者不会阻止作者,作家不会阻止读者。此外,读者将无法从其他事务中读取任何飞行数据修改。

正如我已经提到的,这两个都使用行版本控制。当使用行版本控制时,SQLServer中的数据库引擎将维护受事务影响的行的版本。利用行版本控制将:

消除读取事务上的共享锁。

减少阻塞(在读事务上)。

增加数据修改所需的资源。

增加TEMPDB中的活动(存储行版本信息的地方)。

所有数据库数据修改都将具有行版本控制。

每个数据记录将附加一个14字节的记录后缀。

并发效应

上面的图表提到了几种不同的并发副作用,所以让我们来解释其中的每一个。这些效应在BOL中被定义为并发效应:

当第二个事务选择另一个事务正在更新的行时,脏读取(在ISO中称为“未提交依赖项”)发生。当其他事务实际提交修改数据的事务之前,正在读取修改后的数据时会出现脏读取。如果要回滚该事务,则第二个事务刚刚返回了一个行,该行中存在不存在于数据库中的数据。可以通过防止读取正在改变的数据来避免这种影响。

当事务多次读取同一行时,不可重复读取(在ISO中称为“不一致分析”),并且不同读取之间的结果是不同的。当另一个事务修改并提交对行的更改时,可能发生这种情况。虽然类似于脏读取,但不同之处在于,在不可重复读取中,写入事务已成功提交事务,而在脏读取中,写入事务被回滚。通过防止数据的变化,直到数据读完为止,可以避免这种影响。

当读取数据的事务正在读取数据范围时,将发生幻像读取,而另一事务则插入或删除行。如果将再次发布读事务的语句,则将返回(插入事务)的额外行,或返回的行数较少(对于删除事务)。通过防止事务在读取数据时插入或删除数据,可以避免这种影响。

缺失/双读发生在:

读取事务在索引扫描操作中读取行的范围,并且在读取期间,通过第二事务更新行,改变索引键列,从而改变其在扫描中的位置。如果更新将行从扫描结束移动到开始,则读取事务可能错过读取该行;反之,如果更新从扫描的开始移动到结束,则该行可以被读取两次。

如果读取未提交隔离级别中的读取事务正在执行分配顺序扫描(使用IAM页),而另一事务导致页拆分,则读取事务将丢失行。

当你阅读这些效果时,你应该能够看到,当你工作以防止这些并发效应时,你在数据库中创建了更多的锁定(从而潜在地阻止更多的阻塞)。

并发效应的示例

让我们运行一些示例,看看这些不同的并发效应如何在不同的事务隔离级别中表现出来。所有这些示例都是通过使用两个查询窗口来工作的:一个将运行一个读事务,另一个运行写事务。查询利用“WAITFOR DELAY”给你一点时间来启动一个事务,并切换到另一个查询窗口来运行另一个查询窗口。

首先是数据库初始化代码。此代码需要在运行每个测试之前运行。它被放入一个存储过程中,以便可以在必要时轻松运行。

IF DB_ID('IsolationLevelTest')ISNOTNULLBEGIN
 USE IsolationLevelTest;
 ALTERDATABASE IsolationLevelTest SET SINGLE_USER WITHROLLBACK IMMEDIATE;
 USE master;
 DROPDATABASE IsolationLevelTest;END;CREATEDATABASE IsolationLevelTest;
GOUSE IsolationLevelTest;
GO
CREATEPROCEDURE dbo.db_reset ASIF OBJECT_ID('dbo.IsolationTests','U')ISNOTNULLDROPTABLE dbo.IsolationTests;CREATETABLE dbo.IsolationTests ( 
Id INTEGER IDENTITY, 
ColA CHAR(1));INSERTINTO dbo.IsolationTests(ColA)SELECT'A'UNIONALLSELECT'A'UNIONALLSELECT'A'UNIONALLSELECT'A'UNIONALLSELECT'A'UNIONALLSELECT'A'UNIONALLSELECT'A';
SELECT *FROM dbo.IsolationTests;
IFEXISTS(SELECT 1 FROM sys.databases WHERE database_id = DB_ID('IsolationLevelTest')AND snapshot_isolation_state = 1)
 ALTERDATABASE IsolationLevelTest SET ALLOW_SNAPSHOT_ISOLATION OFF;
GOEXECUTE dbo.db_reset;
GO

未提交读

在未读的隔离级别中,我们将查看如何允许脏读取。这将通过在正在执行更新的一个查询窗口中启动事务,并在读取未提交事务隔离级别中运行SELECT语句的第二查询窗口中执行,以便查询将读取正在修改的数据。经过一段时

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于redis持久化的几种方式介绍 下一篇mysql优化之mysql查询性能排序分析

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目