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;

一旦第一个会话完成其事务,然后释放锁,第二个会话就也会完成。

posted @ 2023-01-30 21:39  平元兄  阅读(203)  评论(0编辑  收藏  举报