我有以下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,第二个开始显示测试表内容而第一个终止。
由于
答案 0 :(得分:3)
SERIALIZABLE以最基本的方式“持有更长时间的锁”。当您选择SELECT时,保持锁是一个共享锁,允许其他读者。
如果您想阻止读者,请使用WITH (TABLOCKX)
提示进行独占锁定,而不需要SERIALIZABLE。或者带有SERIALIZABLE的XLOCK
换句话说:
TABLOCK =粒度=锁定的内容
TABLOCKX =合并
答案 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