SQL Server是否保证顺序插入标识列?

bal*_*pha 13 sql-server identity-column sql-server-2008

换句话说,以下"光标"方法是否有效:

  1. 从DB检索行
  2. 保存返回记录中的最大ID以供日后使用,例如在 LastMax
  3. 后来, "SELECT * FROM MyTable WHERE Id > {0}", LastMax

为了使其工作,我必须确保我在步骤1中没有得到的每一行都有一个大于的Id LastMax.这是保证,还是我可以遇到奇怪的竞争条件?

Tho*_*mas 18

保证绝对在任何情况下都不可能获得可能小于或等于当前最大值的值?不,没有这样的保证.也就是说,这种情况可能发生的情况是有限的:

  1. 有人禁用标识插入并插入值.
  2. 有人重新设置了标识列.
  3. 有人改变增量值的符号(即代替+1,它改为-1)

假设没有这些情况,您就可以避免竞争条件造成下一个值低于现有值的情况.也就是说,无法保证行将按其身份值的顺序提交.例如:

  1. 打开一个事务,使用标识列插入到表中.假设它得到值42.
  2. 在同一个表中插入并提交另一个值.让我们说它的价值43.

在第一个交易提交之前,43存在但42则不存在.标识列只是保留一个值,它不是指示提交的顺序.

  • +1第二部分恰好是我的问题 - 因此你的回答是"不",因为如果我在43次被投入和42次被提交的时间之间进行我的第一次检索,我将永远不会知道第42行 (4认同)

Wol*_*ang 6

我认为这可能会出错,具体取决于事务的持续时间,请考虑以下事件顺序:

  1. 交易A开始
  2. 事务 A 执行插入 - 这会在标识列中创建一个新条目
  3. 交易B开始
  4. 事务 B 执行插入 - 这会在标识列中创建一个新条目
  5. 事务B提交
  6. 您的代码执行其选择并查看第二笔交易的身份值
  7. 事务 A 提交 -

您的代码永远不会找到事务 A 插入的行。执行步骤 6 时尚未提交。当执行下一个查询时,将找不到它,因为它在标识列中的值低于查询正在查找的值。

如果您使用读未提交隔离模式执行查询,它可能会起作用