【问题标题】:Why Identity Columns does not participate in transaction?为什么 Identity Columns 不参与交易?
【发布时间】:2013-03-24 22:32:28
【问题描述】:

假设我有下面的

Begin Tran

Insert Into tbl(name) values('name1');

Insert Into tbl(name) values('name2');


Rollback

End

tbl 表有一个标识列(id)和一个 varchar 列(名称)。

现在显然数据将被回滚。

当我再次尝试插入记录时,Id 列的值为 3 而不是 1!

为什么?为什么 Identity 列的值不参与交易?它存储在哪里?等等

我已经阅读了thisthis,但我仍然需要更深入的信息。

提前致谢

【问题讨论】:

  • 为什么链接到问题/答案不充分?你还期待什么?
  • 先生,最近我听说,由于列值一直保存在某些系统表中,因此它不能参与事务,因为它们不是要这样做的(系统表)。是真的吗?如果是这样,那么我想了解更多有关它的信息吗?还是我收集到的信息完全错误?
  • 它不参与事务的原因是因为设计决定它不参与事务。关于它的存储位置等的任何其他内容都是偶然的。

标签: sql-server


【解决方案1】:
T1:                      |  T2
begin                    |  begin     
insert <-- gets ID 1     |
                         |    insert <-- gets ID 2
rollback                 |

现在只有在 id 生成“参与事务”的情况下,T1 回滚后,下一个 ID 应该是什么值才能回答...

【讨论】:

  • 是的。这比仅仅引用文档要好得多,因为它说明了为什么 SQL Server 的设计者必须这样做(除了表锁来序列化访问......)。
【解决方案2】:

您可以查看MSDN 本身:

... “值的重用——对于给定的具有特定身份的身份属性 种子/增量,标识值不被引擎重用。如果一个 特定的插入语句失败或插入语句是否滚动 那时消费的身份值会丢失并且不会 再次生成。这可能会导致随后的身份出现空白 值产生。 "

“这些限制是设计的一部分,以便改进 性能,并且因为它们在许多常见的情况下是可以接受的 情况。如果您因为这些原因而无法使用身份值 限制,创建一个单独的表来保存当前值和 管理对表格和编号分配的访问 申请。”

我认为简单的原因是种子没有为该列设置,因为它的生成方式如下:

每个新值都是根据当前的种子和增量生成的

更改seed 值可能会导致并发插入更加混乱,并且与UNIQUEPRIMARY KEY 结合使用,插入可能更容易“死亡”,特别是在事务繁重的环境中。

【讨论】:

    猜你喜欢
    • 2015-02-06
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多