UPDLOCK 和 FOR UPDATE 的区别

ama*_*ers 4 sql-server t-sql locking

给出以下代码:

Set conn = CreateObject("ADODB.Connection")
Set RS = CreateObject("ADODB.Recordset")
conn.BeginTrans
...
//This is the line it is about
RS.Open "SELECT a,b FROM c FOR UPDATE", conn, adOpenDynamic, adLockPessimistic
...
RS.Close
conn.CommitTrans
conn.Close
Run Code Online (Sandbox Code Playgroud)

我使用时有什么区别:

RS.Open "SELECT a,b FROM c (UPDLOCK)", conn, adOpenDynamic, adLockPessimistic
Run Code Online (Sandbox Code Playgroud)

更新:

现在我们使用 FOR UPDATE 但看起来表没有锁定。SQL Profiler 向我们展示了这一点:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

declare @p1 int  set @p1=NULL  declare @p3 int  set @p3=229378  declare @p4 int  set @p4=163842  declare @p5 int  set @p5=NULL  exec sp_cursoropen @p1 output,N'SELECT a,b FROM c FOR UPDATE',@p3 output,@p4 output,@p5 output  select @p1, @p3, @p4, @p5 

UPDATE c SET a = a + 1 WHERE b = 'Value' 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

IF @@TRANCOUNT > 0 COMMIT TRAN 
Run Code Online (Sandbox Code Playgroud)

我们使用的更新语句:

SQL = "UPDATE c SET a = a + 1 WHERE b= 'Value'"
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 6

FOR UPDATE不是常规 SQL 语句中的有效 SQL Server 语法,它在您创建游标时使用

但是您可能将 ADO 与CursorLocation 一起使用adUseServer,然后您的查询实际上可以工作,因为 ADO 将使用接受用于游标的语法的sp_cursoropen

SQL Server 中的默认行为是可以更新游标,因此for update除非您还指定了列列表,否则指定对您没有任何作用。

updlock如果您在事务中运行,则在游标上指定查询提示只会为您做一些事情。有updlock锁是在你做的时候放的fetch next from ...,没有updlock锁是在你做的时候放的update ... where current of,仍然只有在你处于事务中时。

因此,在您的情况下,updlock如果您在事务中,则使用将在您获取数据时放置锁。如果updlock在事务中不使用, 则会在更新数据时放置锁。如果不存在交易,则两者之间没有区别,您也可以不使用它们中的任何一个。