【问题标题】:How to reset Autoincremented Id when rollback occurs in sqlsql中发生回滚时如何重置自动增量ID
【发布时间】:2013-05-03 12:29:40
【问题描述】:

当我尝试在表中插入新行时,如果该事务发生异常,则数据回滚。

现在当下次成功插入新条目时,AutoIncrement id 将更新为下一个值。表示表中两个连续的唯一 ID 之间存在间隙。

有什么有效的方法可以解决这个问题吗?

提前致谢

【问题讨论】:

  • 你必须使用 TRY,CATCH BLOCK
  • 这到底是什么“问题”? SQL Server 不这样做。请参阅this answer 快速解释和this one 了解实际问题场景。如果您绝对要求您的 ID 中没有间隙,您将必须为此编写自己的逻辑 - 然后弄清楚当您删除记录时该怎么做。
  • 唯一要克服的问题是您期望中的问题。身份列应该被认为是不透明的 blob,只是巧合,可以存储在 int 变量中。应尽可能忽略这些列中包含的实际

标签: sql-server


【解决方案1】:

必须说答案 -

IDENTITY 列的整个想法是有意义,并且与事务无关 - 这样可以在不关心其他事务是否回滚的情况下抛出数字。想象一下,一个每秒 1000 次插入的系统为每个事务(插入)等待 10 毫秒以决定它是否会提交! (仅供参考 10 毫秒 * 100 = 1 秒)

注意:在 SQL Server 2012(撰写本文时的最新 SP/补丁级别)中,on Connect 此处提到了与身份相关的“功能”。

即使在 2012 年之前,您甚至不需要回滚到 使用 IDENTITY 值 - 请参阅此处https://stackoverflow.com/a/16156419/573261


出于同样的原因,这也适用于其他主要的 RDBMS,例如

PostgreSQL sequences

重要提示:为避免阻塞从同一序列中获取数字的并发事务,nextval 操作永远不会回滚;也就是说,一旦获取了一个值,它就被认为是已使用的,即使执行 nextval 的事务稍后中止。这意味着中止的事务可能在分配的值序列中留下未使用的“漏洞”

(强调我的)

【讨论】:

  • 我有 99.9% 的把握,如果 MySQL 或 PostgreSQL 失败,它们都会回滚 #。我不确定为什么 SQL Server 不能这样做,但他们可以。
  • 我同意。做一个简单的“select mySequence.NextVal from dual;”将“用完”该值。试试看。在你的 oracle 世界中运行这个查询 3 次。
  • @RichardTheKiwi 我刚刚对其进行了测试以确保。 PostgreSQL 在插入之前验证插入或其他内容。如果你创建一个 varchar(10) 列,插入一个超过 10 个字符的字符串,然后插入一条有效记录,你得到 ID 1。在 SQL Server 中你得到 ID 2。
  • @Phill 我特意画了一条线,让 PostgreSQL 注释自己留下。它指的是序列中的间隙,而不是两个 SQL Server 怪癖中的任何一个的可重复性。
  • @RichardTheKiwi - 好吧。你的链接对我来说没有多大意义。 Serial 中的注释对我来说更有意义 - postgresql.org/docs/9.2/static/… 请注意。干杯。
猜你喜欢
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 1970-01-01
相关资源
最近更新 更多