我们有一个附加+只读的表。我们希望多个应用程序以一种廉价且简单的方式(无需更改跟踪)使用该数据库中显示的所有新行。
让每个应用程序记录最后一个 ID 的简单建议似乎并不安全。假设 3 个连接(2 个作者和 1 个读者)这样做:
W1: BEGIN TRAN, INSERT 1000 Records (IDs 1-1000)
W2: BEGIN TRAN, INSERT 1000 Records (IDs 1001-2000)
W2: COMMIT
R1: SELECT * WHERE Id > 0 (last sync value)
W1: COMMIT (or possibly ROLLBACK)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,阅读器将获得记录 1001-2000,并将 2000 保存为最高 ID。显然这是不正确的。假设各种编写器以不同的速度运行(因此我们永远不能假设它们会因延迟或性能而按顺序提交),有哪些选择?
我们是否必须求助于更改跟踪之类的方法,或者要求每个应用程序保存最后的 (batch*writers*x) ID 并重新读取它们以确保它们没有遗漏任何一个?
回滚和序列中的其他间隙(MSSQL 可以将 ID 跳转 1000;很确定其他 DB 在某些情况下会这样做)使得尝试猜测是否跳过行变得很复杂。另外,批量插入可能不是正确的批次;它们可以由多个 INSERT 语句组成,这意味着每个 tx 甚至可能没有分配一个连续的 ID 块。
如果有特定于该系统的 hack,我们目前正在使用 MSSQL 2012,但我对一般情况更感兴趣。