SQL Server:可序列化级别无法正常工作

时间:2010-12-29 12:43:09

标签: sql sql-server stored-procedures

我有以下SP:

CREATE PROCEDURE [dbo].[sp_LockReader]  
AS  
BEGIN  
SET NOCOUNT ON;  
begin try   
set transaction isolation level serializable  
begin tran  
select * from teste  
commit tran  
end try  
begin catch  
rollback tran  
set transaction isolation level READ COMMITTED  
end catch  
set transaction isolation level READ COMMITTED  
END  

表“test”有很多值,因此“select * from teste”需要几秒钟。我在两个不同的查询窗口中同时运行sp_LockReader,第二个开始显示测试表内容而第一个终止。

  • 不应该序列化级别强制第二个查询等待吗?
  • 我如何获得描述的行为?

由于

3 个答案:

答案 0 :(得分:3)

SERIALIZABLE以最基本的方式“持有更长时间的锁”。当您选择SELECT时,保持锁是一个共享锁,允许其他读者。

如果您想阻止读者,请使用WITH (TABLOCKX)提示进行独占锁定,而不需要SERIALIZABLE。或者带有SERIALIZABLE的XLOCK

换句话说:

  • SERIALIZABLE =隔离级别=锁定持续时间,并发性
  • XLOCK = mode = sharing / exclusivity
  • TABLOCK =粒度=锁定的内容

  • TABLOCKX =合并

See this question/answer for more info

答案 1 :(得分:1)

可序列化的事务,其输出不受其他并发事务的影响。在您的情况下,您从表中选择两次;这些事务都不会改变另一个事务的结果集,因此它们可能同时运行。

即使一个事务确实更新了表,这也不一定会阻止另一个事务执行,因为数据库可以从快照中工作。

在这里查看一下比我能提供的更好的解释... http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

答案 2 :(得分:0)

这里有另一个注意事项。如果您在SERIALIZABLE隔离下使用XLOCK,则其他具有READ COMMITTED隔离的事务仍然可以读取XLOCK的行。

为防止这种情况,请使用PAGLOCK和XLOCK。 详情请见此处 http://support.microsoft.com/kb/324417