乐观锁定实际上如何强制重新读取/更新?

Mar*_*ara 1 rdbms locking update

乐观锁的理解是,它使用表中每条记录的时间戳来确定记录的“版本”,这样当记录被多个进程同时访问时,每个记录的版本都有一个引用.

然后,当执行更新时,更新时间戳。在提交更新之前,它会第二次读取记录上的时间戳。如果它拥有的时间戳(版本)不再是记录上的时间戳(因为它自第一次读取以来已被更新),则该过程必须重新读取整个记录并将更新应用于它的新版本。

因此,如果我所说的任何内容不正确,请首先为我澄清。但是,假设我在这里或多或少是正确的......

这实际上如何在 RDBMS 中体现出来?这是在应用程序逻辑(SQL 本身)中强制执行的第二次读取/验证还是 DBA 制定的调整参数/配置?

我想我想知道读取时间戳并在时间戳陈旧时执行第二次更新的逻辑来自哪里。所以我问:是应用程序开发人员强制执行乐观锁,还是由 DBA 强制执行?无论哪种方式,如何?提前致谢!

Con*_*lls 5

基本技术非常简单。当您阅读记录时,您会记下版本或时间戳列,例如

Select FooID
      ,Foo
      ,Bar
      ,TS      -- timestamp
  from Foobar
 where FooID = @FooID
Run Code Online (Sandbox Code Playgroud)

当您写出记录时,您可以通过时间戳/版本过滤写入,以便在时间戳/版本发生变化时写入不会写入任何内容。这使得写入原子,例如

update Foo
   set Foo = @foo
      ,Bar = @bar
      ,TS = @timestamp  
 where FooID = @FooID
   and ts = @timestamp

select @row_count = @@rowcount  -- specific to t-sql, but this is a system variable
                                -- that holds the number of rows affected by the
if @@rowcount = 0               -- most recent operation.  Other DBMS platforms do
    [deal with outdated record] -- this differently.
Run Code Online (Sandbox Code Playgroud)

这允许应用程序在不打开锁的情况下进行更新。这对于通过连接池工作的 n 层系统是必要的,并防止了过去在两层客户端-服务器系统上常见的一类死锁。

数据库中没有强制执行此操作。这一切都由应用程序明确完成。