考虑到以下代码:
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当我使用:
RS.Open "SELECT a,b FROM c (UPDLOCK)", conn, adOpenDynamic, adLockPessimistic更新:
现在我们使用UPDATE,但是表看起来没有被锁定。SQL事件探查器向我们展示了以下内容:
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 我们使用的update语句:
SQL = "UPDATE c SET a = a + 1 WHERE b= 'Value'"发布于 2013-02-27 10:21:39
FOR UPDATE在常规SQL语句中不是有效的Server语法,它在创建游标时使用。
但是您可能在CursorLocation adUseServer中使用ADO,而您的查询实际上是有效的,因为ADO将使用服务提供商_集束器,后者接受用于游标的语法。
Server中的默认行为是可以更新游标,因此,除非还指定列列表,否则指定for update不会对您产生任何影响。
在游标上指定updlock查询提示只会在事务中运行时才会为您做一些事情。使用updlock时,锁是在执行fetch next from ...时放置的,而在没有updlock的情况下,锁是在执行update ... where current of时放置的,仅当您处于事务中时。
因此,在您的示例中,如果您在事务中获取数据,使用updlock将放置锁。如果您不使用updlock,在事务中,您将在更新数据时放置锁。如果不存在任何事务,则两者之间没有区别,您也可以不使用它们中的任何一个。
发布于 2013-02-27 09:42:44
总的来说-没有什么区别。、DB2、MySql用于更新,但在Server中可以使用UPDLOCK查询。结果是相同的-它阻塞选定的行来为表进行更新。但实施的方式有点不同。在Server中,它有时不仅在行级别上进行锁定,而且在页级甚至表级别上进行锁定。main -它阻塞了新选择的结果(因此有时您可能会遇到死锁问题)。Oracle只在行级别上进行锁定,它们可用于select。据我所知,使用这些服务器特性并不是最佳实践,因此尽量避免使用它们。
https://dba.stackexchange.com/questions/35532
复制相似问题