sql server 2008 有一个表主键id设置为 identity(1,1) ,在 insert 时看不到记录但是 id 项已递增。
求解。
------解决思路----------------------
identity列,不管插入失败还是成功,都会一直自增
因此,你INSERT后看不到记录,很明显是失败了
------解决思路----------------------
很正常啊,就是应该这样的。
你可以想象这样的场景:
1)会话A插入、事务尚未递交,分配1
2)会话B插入、事务尚未递交,分配2(不能也分配1,否则就重复了)
3)会话C插入、事务递交,分配3(不能也分配1或2,否则就重复了)
4)会话A事务回滚
5)会话B事务回滚
很明显只要有插入,id必须递增,否则就会重复。
那么去掉步骤2~4,只留下会话A,是先递增了id再回滚了插入的,就是你的场景。
------解决思路----------------------
你们应该有记录失败日志吧
还有另外一种可能,就是没有INSERT失败,而是因事务失败,合法的回滚了数据,
------解决思路----------------------
这个日志里肯定是没有的,除非你的程序中有这种机制,就是 再事务失败的时候,记录相应的报错信息和相应的语句,否则肯定是很难监控到这种报错的信息的
------解决思路----------------------
如果语句和事务失败,它们会更改表的当前标识,从而使标识列中的值出现不连贯现象。即使未提交试图向表中插入值的事务,也永远无法回滚标识值。例如,如果因 IGNORE_DUP_KEY 冲突而导致 INSERT 语句失败,表的当前标识值仍然会增加。
联机帮助原话
------解决思路----------------------
这个是很容易测试出来的
create table #test (id int identity(1,1),name varchar(3))
insert into #test (name)
select '1'
insert into #test (name)
select 'asssdfasdfaggg'
insert into #test (name)
select '3'
select * from #test
可以看到错误提示,在第二句insert会发生字符串截断错误,导致插入失败,再插入一条就会发现标识值是已经增加了的
------解决思路----------------------
如业务不太繁忙的话,开一下 sql profiler ,监控一段时间,直到发现了这个情况,再把语句都找出来,看看哪个执行失败了,就知道程序哪里有问题了。
------解决思路----------------------
#8 的例子也举得很好。

先准备好插入的数据(分配了id),再进行数据校验,不成功也会消耗掉一个id。