返回首页
当前位置: 主页 > 数据库 > Mssql教程 >

MS SQL Update锁介绍

时间:2015-08-12 00:47来源:电脑教程学习网 www.etwiki.cn 编辑:admin

UPDATE 锁并不是一种单独的锁类型,倒是有点像是SHAREDEXCLUSIVE锁的混合。并且可能与你认为的不同,UPDATE 锁不是由UPDATE操作获取的。 当SQL Server执行一个数据修改操作,但是需要首先执行一个检索来查找需要修改的资源时,事务会获取这种类型的锁。

SQL Server搜索时,它不需要获取EXCLUSIVE锁,只有在找到要更改数据时,才需要EXCLUSIVE锁。通常情况下,如果SQL Server进程只是搜索数据,它会在所访问到的每个资源上获取SHARED锁,然后确定是否已经找到了正在搜索的数据。但是,如果要搜索的数据是用来修改的话,SQL Server启用SHARED锁则存在潜在问题。例如,两个进程都是寻找相同的资源(如Customers表中同一客户行)进行修改,使用不同的访问的路径,并且它们在同一时间达到所需的资源。如果它们都在检索的数据上获取SHARED锁,它们都可以同时锁定要修改的资源,但在它们进行修改前需要将锁转换为EXCLUSIVE锁。 由于另一个进程具有了SHARED锁,则不会生成EXCLUSIVE锁。 每个进程都具有一个SHARED锁,并且每个都尝试将其转换为EXCLUSIVE的锁,但是都会由于另外一个进程的存在,这两个尝试都不会成功。这是一种死锁情况,叫做“转换死锁”。

UPDATE 锁是一种死锁避免机制。如果SQL Server使用UPDATE锁,则死锁将不会发生。 如果SQL Server进程开始了一个最终要修改数据的搜索操作,它获取UPDATE锁,直到找到要修改的数据。 UPDATE 锁与SHARED锁兼容,但与EXCLUSIVE锁或其他UPDATE锁不兼容。 因此,如果两个进程正在寻找相同的数据资源,则第一个到达的进程会获取到UPDATE锁,然后在第二个进程无法取得任何锁定,并且将等待第一个进程处理完成。由于第一个进程没有被阻塞,它可以将其UPDATE锁转换为EXCLUSIVE锁,并完成事务处理后释放锁,然后在第二个进程进行其他修改。

 sys.dm_tran_locks 视图中,request_mode值为U的代表 UPDATE 锁。

来看一下UPDATE锁:

[我正在使用旧的示例数据库 pubs。 如果要尝试下面的代码可以单击这里下载]

-- Close all existing connections and start a new one

-- Step 1: 
USE pubs; 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;


BEGIN TRAN; 
UPDATE authors 
SET contract = 0 
WHERE au_lname = 'Ringer' ;

---- Step 2: Open a second connection window uncomment once, 
--   so the ROLLBACK is still commented. Execute…

--USE pubs; 
--SET TRANSACTION ISOLATION LEVEL READ COMMITTED ;

--BEGIN TRAN; 
--UPDATE  authors 
--SET city = 'Provo' 
--WHERE  state = 'UT';

-- You should be blocked.

---- ROLLBACK TRAN;

-- Step 3: Go back to the first connection window and run the following 
SELECT request_session_id AS session_id, DB_NAME(resource_database_id) AS [database], 
   request_mode AS mode, resource_type as [type],  
   resource_associated_entity_id AS entity, 
   resource_description,  request_status AS status 
FROM sys.dm_tran_locks; 
COMMIT TRAN;

你将会得到类似下面的输出结果:

 

注意KEYWAIT状态的U锁,它具有与第一个连接所GRANTKEY相同的资源描述。现在COMMITROLLBACK第一个连接,你会看到第二个连接所等待的KEY上获得X锁,还有在另一个KEY上的X锁。

 

我提及UPDATE锁的目的是说明“修改数据的意向”,因此你可能会认为UPDATE的锁是类似于INIENT锁。 不是这样的,UPDATE锁指示一个更改锁锁模式的意向,而INTENT锁指示一个更改锁粒度的意向。

------分隔线----------------------------
标签(Tag):sqlserver sqlserver数据库 数据库 sqlserver200
------分隔线----------------------------
推荐内容
猜你感兴趣