当前位置: 代码迷 >> Sql Server >> sql server 2008 insert 失败但是identity项已递加
  详细解决方案

sql server 2008 insert 失败但是identity项已递加

热度:42   发布时间:2016-04-24 09:12:12.0
sql server 2008 insert 失败但是identity项已递增
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。
  相关解决方案