Tsql 大型过程中的SQL隔离级别或锁
我有处理用户操作的大型存储过程 它们由多个select语句组成。这些是经过过滤的,大多数情况下只得到一行。所选内容将复制到可诱惑项中或以其他方式进行计算。 最后,merge语句在数据库中执行所需的更改。 所有内容都封装在一个事务中 我有来自用户的并发输入,select语句的选定行应该被锁定以保持数据完整性 如何锁定所有select语句的选定行,以便在当前事务处理过程中不会通过其他事务更新它们? ROWLOCK和HOLDLOCK的表提示组合是否只锁定选定的行,或者整个表是否因为HOLDLOCK而被锁定Tsql 大型过程中的SQL隔离级别或锁,tsql,stored-procedures,transactions,Tsql,Stored Procedures,Transactions,我有处理用户操作的大型存储过程 它们由多个select语句组成。这些是经过过滤的,大多数情况下只得到一行。所选内容将复制到可诱惑项中或以其他方式进行计算。 最后,merge语句在数据库中执行所需的更改。 所有内容都封装在一个事务中 我有来自用户的并发输入,select语句的选定行应该被锁定以保持数据完整性 如何锁定所有select语句的选定行,以便在当前事务处理过程中不会通过其他事务更新它们? ROWLOCK和HOLDLOCK的表提示组合是否只锁定选定的行,或者整个表是否因为HOLDLOCK而被
SELECT *
FROM dbo.Test
WITH (ROWLOCK HOLDLOCK )
WHERE id = @testId
我可以改用
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
就在交易开始之后?还是把整张桌子都锁上了?
我使用的是SQL2008 R2,但如果SQL2012中的工作方式不同,我也会感兴趣
PS:我刚刚读到关于表提示UPDLOCK和SERIALIZE的内容。UPDLOCK似乎是一种只锁定一行的解决方案,而且似乎UPDLOCK总是锁定而不是ROWLOCK,ROWLOCK只指定如果应用了锁,锁是基于行的。我仍然对解决这个问题的最佳方法感到困惑…更改隔离级别修复了问题(并锁定在行级别): 下面是我如何测试它的。 我在SQL Management Studio的空白页中创建了一条语句:
begin tran
select
*
into #message
from dbo.MessageBody
where MessageBody.headerId = 28
WAITFOR DELAY '0:00:05'
update dbo.MessageBody set [message] = 'message1'
where headerId = (select headerId from #message)
select * from dbo.MessageBody where headerId = (select headerId from #message)
drop table #message
commit tran
在执行此语句时(由于延迟,最后需要5秒),我在另一个窗口中调用了第二个查询:
begin tran
select
*
into #message
from dbo.MessageBody
where MessageBody.headerId = 28
update dbo.MessageBody set [message] = 'message2'
where headerId = (select headerId from #message)
select * from dbo.MessageBody where headerId = (select headerId from #message)
drop table #message
commit tran
我很惊讶它是瞬间执行的。这是由于默认的SQL Server事务级别“Read Committed”。由于第一个脚本的更新是在延迟之后完成的,因此在第二个脚本期间还没有提交的更改,因此读取并更新第28行
将隔离级别更改为序列化阻止了这一点,但也阻止了并发-两个SCIPT都是连续执行的
这没问题,因为两个脚本都读取并更改了同一行(通过headerId=28)。在第二个脚本中将headerId更改为另一个值,这些语句并行执行。因此,序列化的锁似乎位于行级别
添加表提示
WITH ( SERIALIZABLE)
在第一个语句的第一个select中,也会阻止对所选行的进一步读取。您有几个问题,这些问题都包含在文档中。为什么您会认为HOLDLOCK会改变锁?我知道HOLDLOCK强制锁,希望与rowlock结合使用时,只锁定单个行。我澄清了问题,我可以删除问题之后的所有内容,但这可能有助于理解问题。
WITH ( SERIALIZABLE)