18.1 SQL Server阻塞
SQL Server阻塞
目录
简介
当两个会话试图同时更新同一数据时,会发生阻塞。
第一个会话锁定数据,第二个会话需要等待第一个会话完成并释放锁定。
结果,第二会话被阻止更新数据。一旦第一会话完成,第二会话恢复操作。
通常,当一个会话持有资源上的锁,而第二个会话试图获取同一资源上的冲突锁类型时,就会发生阻塞。
下图说明了SQL Server阻塞:

通常,第一个会话锁定数据的时间很短。当它释放锁时,第二个会话可以获取它自己对资源的锁并继续处理。
阻塞是基于锁的并发的SQL Server不可避免的设计特性。这是正常行为,不会影响服务器性能。
示例
先创建一个新的HR数据库,其中包含一个名为People的表,用于演示:
| DROP DATABASE IF EXISTS HR; | |
| GO | |
| CREATE DATABASE HR; | |
| GO | |
| USE HR; | |
| CREATE TABLE People ( | |
| Id int IDENTITY PRIMARY KEY, | |
| FirstName varchar(50) NOT NULL, | |
| LastName varchar(50) NOT NULL | |
| ); | |
| INSERT INTO People (FirstName, LastName) | |
| VALUES ('Jane', 'Doe'); | |
| SELECT * FROM People; |
People表有一行Id为1。
首先,开始一个事务并将Id为1的行的LastName更新为“Smith”:
| BEGIN TRAN; | |
| UPDATE People | |
| SET LastName = 'Smith' | |
| WHERE Id = 1; |
注意,我们没有在第一个会话中提交或回滚事务。
然后,创建一个新会话。在第二个会话中,将id为1的行的LastName更新为“Brown”:
| BEGIN TRAN; | |
| UPDATE People | |
| SET LastName = 'Brown' | |
| WHERE Id = 1; | |
| COMMIT; |
由于第一会话中的事务正在进行,所以第二会话将等待第一会话完成。
如果使用SQL Server Management Studio,将看到以下消息:
| Executing query.... |
要列出当前连接到SQL Server的所有进程,使用sp_who2存储过程。
| sp_who2; |
输出显示系统进程ID(SPID)55被SPID 69阻塞。在本例中,第一个会话为69,而第二个会话为55。注意,你的SPID可能与本例中的不同。

第三步,返回第一个事务并提交:
| COMMIT; |
一旦第一个会话完成其事务,然后释放锁,第二个会话就也会完成。
分类: SQL Server
漫思
浙公网安备 33010602011771号