7

我以前从未见过这种情况,非常奇怪。

我有一个正在开发的本地 SQL Server 2012 Express 数据库。使用 TestDrive 插件运行一组简单的测试并使用 EF v5 访问数据库。

我刚刚运行了一个将记录插入数据库的测试。我在表中有 9 行从 id 1-9 开始。下一个插入和 ID 正好跳了 10000 !!!!

Id 列是:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10009

我知道失败的插入也会增加 ID,但我可以保证 10,000 在测试运行之间的 5 秒内没有插入失败......

表结构非常简单,一堆列和一个自动递增,类型bigint(长)的标识列,没有 SP、触发器或任何其他程序化内容。

[Id] [bigint] IDENTITY(1,1) NOT NULL,

很困惑,有没有人看到过这种情况?

4

2 回答 2

2

这篇博文有一些额外的细节。它看起来像在 2012 年,identity被实现为一个序列。默认情况下,一个序列有一个缓存。如果缓存丢失,您将丢失缓存中的序列值。

建议的解决方案是创建一个序列no cache

CREATE SEQUENCE TEST_Sequence
    AS INT
    START WITH 1
    INCREMENT BY 1
    NO CACHE

据我所见,身份列后面的序列是不可见的。您不能更改它的属性来禁用缓存。

要将其与 Entity Framework 一起使用,您可以将主键设置StoredGeneratedPatternComputed. instead of insert然后您可以在触发器中生成身份服务器端:

if exists (select * from sys.sequences where name = 'Sequence1')
    drop sequence Sequence1
if exists (select * from sys.tables where name = 'Table1')
    drop table Table1
if exists (select * from sys.triggers where name = 'Trigger1')
    drop trigger Trigger1
go
create sequence Sequence1
    as int
    start with 1
    increment by 1
    no cache
go
create table Table1
    (
    id int primary key,
    col1 varchar(50)
    )
go
create trigger Trigger1
    on Table1
    instead of insert
as
insert  Table1
        (ID, col1)
select  next value for Sequence1
,       col1
from    inserted
go
insert Table1 (col1) values ('row1');
insert Table1 (col1) values ('row2');
insert Table1 (col1) values ('row3');

select  * 
from    Table1

如果您找到更好的解决方案,请告诉我:)

于 2012-12-01T08:28:56.267 回答
0

如果您在每次插入查询后调用“检查点”命令,它将解决您的问题。

有关详细信息,请阅读 SQL Server 中的检查点

于 2013-04-08T13:02:04.960 回答