请问 WITH ( UPDLOCK, HOLDLOCK )是什么用法

时间:2021-03-01 02:41:38
Asp.net的Membership表的CreateUser存储过程中为什么要加 WITH ( UPDLOCK, HOLDLOCK )锁呢?

另外with这里是个函数吗?后面可以跟多个参数? 能讲下with()的用法吗


IF (@UniqueEmail = 1)
BEGIN
IF (EXISTS (SELECT *
FROM dbo.aspnet_Membership m WITH ( UPDLOCK, HOLDLOCK )
WHERE ApplicationId = @ApplicationId AND LoweredEmail = LOWER(@Email)))
BEGIN
SET @ErrorCode = 7
GOTO Cleanup
END
END

19 个解决方案

#1


IF (@UniqueEmail = 1) BEGIN IF (EXISTS (SELECT * FROM dbo.aspnet_Membership m WITH ( UPDLOCK, HOLDLOCK ) WHERE ApplicationId = @ApplicationId AND LoweredEmail = LOWER(@Email))) BEGIN SET @ErrorCode = 7 GOTO Cleanup END END

#2


不是函数,是表提示,你可以在联机丛书中输入提示来看含义,这个是强制在查询过程中锁住这些数据

#3


HOLDLOCK 等价于使用可序列化并发模式,UPDLOCK 
Specifies that update locks are to be taken and held until the transaction completes. UPDLOCK takes update locks for read operations only at the row-level or page-level. If UPDLOCK is combined with TABLOCK, or a table-level lock is taken for some other reason, an exclusive (X) lock will be taken instead. 

When UPDLOCK is specified, the READCOMMITTED and READCOMMITTEDLOCK isolation level hints are ignored. For example, if the isolation level of the session is set to SERIALIZABLE and a query specifies (UPDLOCK, READCOMMITTED), the READCOMMITTED hint is ignored and the transaction is run using the SERIALIZABLE isolation level. 


不过我觉得这样写不好

#4


如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx

#5


引用 4 楼 DBA_Huangzj 的回复:
如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx


大概明白了,是同时为这一行记录加上了S 锁和U锁吗?

#6


可以这样理解,不过有U锁的话S锁就没必要了

#7


引用 4 楼 DBA_Huangzj 的回复:
如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx



大概明白她的含义了,是不是说怕并发造成EMAIL重复? 那么直接加一个S锁不行吗?所有的事务都只能读不写更新或者删除。直到这个用户新增成功或者失败。那为什么要加U锁呢?

#8


WITH ( UPDLOCK, HOLDLOCK )

UPDLOCK和HOLDLOCK一起用到底能达到什么功能呢

#9


大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确

#10


引用 9 楼 DBA_Huangzj 的回复:
大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确


那如果直接对这一行加一个S锁,这个锁是等到这一条语句SELECT完就立即释放,还是都整个事务运行完才释放?

#11


引用 9 楼 DBA_Huangzj 的回复:
大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确


直接加S锁,应该用什么代码?

#12


默认select就加s锁,不用加with提示

#13


行锁的话用rowlock,不过一般数据量不大的时候默认也是行锁

#14


这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

#15


引用 14 楼 yupeigu 的回复:
这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?

#16


引用 15 楼 indusl 的回复:
Quote: 引用 14 楼 yupeigu 的回复:

这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?
S锁默认当查询完毕就释放,而这里是为了直到事务结束才释放

#17


不过这些查询提示相对于,一般的隔离级别的设置,更为灵活,也就是粒度更细。

另外,还有比如 rowlock,tablock,paglock,这个主要是从锁的粒度来说的:

rowlock:行锁
tablock:表锁
paglock:页锁

而xlock,updlock,nolock就是从锁的模式来说的:
xlock:独占锁
updlock:更新锁
nolock:不加锁,一般这个经常用在报表的sql语句上,防止阻塞问题。

#18


引用 15 楼 indusl 的回复:
Quote: 引用 14 楼 yupeigu 的回复:

这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?


直接加s锁不行,因为s锁在默认情况下,语句运行完,就自动释放s锁,就会有有问题,所以加上了holdlock,另外,这个存储过程要达到,在同一时间,只有一个存储过程可以直接运行,而其他的存储过程都要等待,所以加了updlock,因为s锁,是共享锁,所以不会阻塞其他的存储过程,而updlock在某个会话持有后,其他的会话都必须要等待。

#19


该回复于2014-12-02 09:09:55被管理员删除

#1


IF (@UniqueEmail = 1) BEGIN IF (EXISTS (SELECT * FROM dbo.aspnet_Membership m WITH ( UPDLOCK, HOLDLOCK ) WHERE ApplicationId = @ApplicationId AND LoweredEmail = LOWER(@Email))) BEGIN SET @ErrorCode = 7 GOTO Cleanup END END

#2


不是函数,是表提示,你可以在联机丛书中输入提示来看含义,这个是强制在查询过程中锁住这些数据

#3


HOLDLOCK 等价于使用可序列化并发模式,UPDLOCK 
Specifies that update locks are to be taken and held until the transaction completes. UPDLOCK takes update locks for read operations only at the row-level or page-level. If UPDLOCK is combined with TABLOCK, or a table-level lock is taken for some other reason, an exclusive (X) lock will be taken instead. 

When UPDLOCK is specified, the READCOMMITTED and READCOMMITTEDLOCK isolation level hints are ignored. For example, if the isolation level of the session is set to SERIALIZABLE and a query specifies (UPDLOCK, READCOMMITTED), the READCOMMITTED hint is ignored and the transaction is run using the SERIALIZABLE isolation level. 


不过我觉得这样写不好

#4


如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx

#5


引用 4 楼 DBA_Huangzj 的回复:
如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx


大概明白了,是同时为这一行记录加上了S 锁和U锁吗?

#6


可以这样理解,不过有U锁的话S锁就没必要了

#7


引用 4 楼 DBA_Huangzj 的回复:
如果看不懂英文就看这里:
http://msdn.microsoft.com/zh-cn/library/ms187373.aspx



大概明白她的含义了,是不是说怕并发造成EMAIL重复? 那么直接加一个S锁不行吗?所有的事务都只能读不写更新或者删除。直到这个用户新增成功或者失败。那为什么要加U锁呢?

#8


WITH ( UPDLOCK, HOLDLOCK )

UPDLOCK和HOLDLOCK一起用到底能达到什么功能呢

#9


大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确

#10


引用 9 楼 DBA_Huangzj 的回复:
大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确


那如果直接对这一行加一个S锁,这个锁是等到这一条语句SELECT完就立即释放,还是都整个事务运行完才释放?

#11


引用 9 楼 DBA_Huangzj 的回复:
大概意思是怕在select 的过程中有另外的会话对数据做了修改,导致第二次select的时候数据不准确


直接加S锁,应该用什么代码?

#12


默认select就加s锁,不用加with提示

#13


行锁的话用rowlock,不过一般数据量不大的时候默认也是行锁

#14


这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

#15


引用 14 楼 yupeigu 的回复:
这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?

#16


引用 15 楼 indusl 的回复:
Quote: 引用 14 楼 yupeigu 的回复:

这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?
S锁默认当查询完毕就释放,而这里是为了直到事务结束才释放

#17


不过这些查询提示相对于,一般的隔离级别的设置,更为灵活,也就是粒度更细。

另外,还有比如 rowlock,tablock,paglock,这个主要是从锁的粒度来说的:

rowlock:行锁
tablock:表锁
paglock:页锁

而xlock,updlock,nolock就是从锁的模式来说的:
xlock:独占锁
updlock:更新锁
nolock:不加锁,一般这个经常用在报表的sql语句上,防止阻塞问题。

#18


引用 15 楼 indusl 的回复:
Quote: 引用 14 楼 yupeigu 的回复:

这个其实就是查询提示,你可以直接在一个sql语句的级别去定义锁,

比如updlock:是获取一个更新锁
holdlock:在一个事务中的sql语句,一直持有这个锁,一般是S锁,直到事务结束为止,其实就类似于REPEATABLE READ,SERIALIZABLE隔离级别

那这个存储过程为什么要同时加上这两个锁呢,直接加一个S锁不行吗?


直接加s锁不行,因为s锁在默认情况下,语句运行完,就自动释放s锁,就会有有问题,所以加上了holdlock,另外,这个存储过程要达到,在同一时间,只有一个存储过程可以直接运行,而其他的存储过程都要等待,所以加了updlock,因为s锁,是共享锁,所以不会阻塞其他的存储过程,而updlock在某个会话持有后,其他的会话都必须要等待。

#19


该回复于2014-12-02 09:09:55被管理员删除

#20