回滚事务中带有 RESEED 的 DBCC CHECKIDENT 的奇怪行为
Weird behavior of DBCC CHECKIDENT with RESEED in a rolled-back transaction
考虑以下 T-SQL 代码(该代码与此 GitHub 存储库 https://github.com/PaloMraz/SqlServerReseedSampleApp 中的 ADO.NET 版本一起可用):
DROP TABLE IF EXISTS __Test;
CREATE TABLE __Test (Id INT IDENTITY NOT NULL PRIMARY KEY);
GO
BEGIN TRAN;
SET IDENTITY_INSERT __Test ON;
INSERT INTO __Test (Id) VALUES (100);
SET IDENTITY_INSERT __Test OFF;
DBCC CHECKIDENT('__Test', RESEED, 1);
ROLLBACK TRAN;
GO
SELECT IDENT_CURRENT('__Test'); -- returns 100 instead of 1
代码执行以下操作:
- 使用 IDENTITY 列创建 __Test table。
- 开始交易。
- 插入新行,将 IDENTITY 种子值覆盖为 100。
- 将 IDENTITY 重新设置为 1。
- 回滚事务。
- 查询当前身份。
我原以为当前身份值会返回 1,但实际上是 100。这意味着事务回滚了插入的行和 DBCC CHECKIDENT 命令的结果,但没有回滚覆盖的 IDENTITY 种子!
这是正确的行为吗?为什么?
感谢您的宝贵时间!
这里唯一真正的问题是为什么 DBCC CHECKIDENT ... RESEED 可以回滚。使用 IDENTITY INSERT 或不插入具有 IDENTITY 列的 table 将增加当前标识值,而不会阻止其他会话生成新 IDENTITY 值的能力。为此,不得在会话事务中登记对当前 IDENTITY 值的修改。
DBCC CHECKIDENT 实际上是一个 DDL 语句,就像 ALTER TABLE。它需要对象上的独占元数据锁,因此可以提交或回滚。 EG
BEGIN TRAN;
DBCC CHECKIDENT('__Test', RESEED, 100);
select *
from sys.dm_tran_locks
where request_session_id = @@spid
ROLLBACK TRAN;
将在目标 table 上显示 Sch-M 锁。
考虑以下 T-SQL 代码(该代码与此 GitHub 存储库 https://github.com/PaloMraz/SqlServerReseedSampleApp 中的 ADO.NET 版本一起可用):
DROP TABLE IF EXISTS __Test;
CREATE TABLE __Test (Id INT IDENTITY NOT NULL PRIMARY KEY);
GO
BEGIN TRAN;
SET IDENTITY_INSERT __Test ON;
INSERT INTO __Test (Id) VALUES (100);
SET IDENTITY_INSERT __Test OFF;
DBCC CHECKIDENT('__Test', RESEED, 1);
ROLLBACK TRAN;
GO
SELECT IDENT_CURRENT('__Test'); -- returns 100 instead of 1
代码执行以下操作:
- 使用 IDENTITY 列创建 __Test table。
- 开始交易。
- 插入新行,将 IDENTITY 种子值覆盖为 100。
- 将 IDENTITY 重新设置为 1。
- 回滚事务。
- 查询当前身份。
我原以为当前身份值会返回 1,但实际上是 100。这意味着事务回滚了插入的行和 DBCC CHECKIDENT 命令的结果,但没有回滚覆盖的 IDENTITY 种子!
这是正确的行为吗?为什么?
感谢您的宝贵时间!
这里唯一真正的问题是为什么 DBCC CHECKIDENT ... RESEED 可以回滚。使用 IDENTITY INSERT 或不插入具有 IDENTITY 列的 table 将增加当前标识值,而不会阻止其他会话生成新 IDENTITY 值的能力。为此,不得在会话事务中登记对当前 IDENTITY 值的修改。
DBCC CHECKIDENT 实际上是一个 DDL 语句,就像 ALTER TABLE。它需要对象上的独占元数据锁,因此可以提交或回滚。 EG
BEGIN TRAN;
DBCC CHECKIDENT('__Test', RESEED, 100);
select *
from sys.dm_tran_locks
where request_session_id = @@spid
ROLLBACK TRAN;
将在目标 table 上显示 Sch-M 锁。