我正在编写一个同步器软件,该软件将在一个数据库中进行所有更改,并将它们同步到另一个数据库。为此,我在表T中添加了两列:

alter table T add LastUpdate rowversion, LastSync binary(8) not null default 0

现在,我可以轻松地选择自上次同步以来已更改的所有行:
select * from T where LastUpdate > LastSync

但是,执行同步后,我应该使两个字段相等。但是更新行也会更新时间戳,所以我必须这样做:
update T set LastSync=@@DBTS+1 where ID=@syncedId

但是我想知道-这将始终有效吗?如果我读取了@@DBTS的值,然后另一个用户在提交行之前设法在某处插入/更新了行,该怎么办?这是危险代码吗?如果是的话-怎么做得更好?

最佳答案

将“LastSync”与真实数据存储在同一张表中可能根本不是一个好主意。
尝试将其存储在另一个没有rowversion的表中。这样就避免了“更新行也会更新时间戳”的问题。

然后,您的同步器软件可以通过以下方式工作:

  • 从附加表
  • 中获取@LastSync值
  • “从T中选择@ThisSync = max(LastUpdate),其中LastUpdate> @LastSync”
  • “从T中选择*,其中LastUpdate> @LastSync和LastUpdate 的行
  • 将@ThisSync作为新的“LastSync”存储在附加表中。

  • 同步运行时修改的条目将具有比max()查询更高的rowversion值。下次调用同步器时,它们将被同步。

    关于sql-server - 此UPDATE语句中是否存在可能的竞争条件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3996146/

    10-11 04:21