3

I have a C# console app which is using a stored procedure to insert rows into a SQL Server database. Currently the database has about 1m rows, however the ID column is up at 26m!

On the last successful insert the ID went from 16m to 26m. The app runs multiple threads in parallel so there is a chance it could be trying to insert two things at the same time.

Is there anything other than a transaction rollback that would cause the identity column to increment without adding a row?

It seems unlikely that there were 10 million times that two threads tried to write a conflicting row at the same time.

I'm using a temporary table variable which is populated by passing XML into the stored proc:

-- insert data if it doesn-t already exist  
insert into DataStore (DataText, DataSourceID)
select distinct td.dataText, td.dataSource 
  from @tempData td
 where not exists ( select 'x' 
                      from DataStore ds 
                     where ds.DataText = td.dataText );
Ben
  • 51,770
  • 36
  • 127
  • 149
finoutlook
  • 2,523
  • 5
  • 29
  • 43
  • 1
    You have a race condition there. That pattern will not work under concurrency [as illustrated here](http://stackoverflow.com/questions/3407857/only-inserting-a-row-if-its-not-already-there) – Martin Smith Dec 28 '11 at 11:37
  • Does `DataText` have a unique constraint on it? Maybe you did actually encounter a whole load of rollbacks. – Martin Smith Dec 28 '11 at 11:44
  • `DataText` doesn't have a constraint, but another column `DateCreated` (populated by default value of `getdate()`) does have one. – finoutlook Dec 28 '11 at 12:59
  • (but `DateCreated` isn't a unique constraint I forgot to mention) – finoutlook Dec 28 '11 at 14:11

2 Answers2

5

What can leave gaps?

  • DELETEs
  • Explicit rollbacks
  • Constraint violations (= implied rollback)
  • SET IDENTITY_INSERT
  • Replication without NOT FOR REPLICATION clause
  • DBCC CHECKIDENT (edit: as per Oleg Dok's answer) ...

I'd also check the increment value using IDENT_INCR in case it is really is 5 million or such

gbn
  • 422,506
  • 82
  • 585
  • 676
2

Inserted and deleted record increments identity counter, as mentioned by @gbn - Rollbacks and c-violations also, but there is two more options:

  • SET IDENTITY_INSERT
  • DBCC CHECKIDENT(..., RESEED)
Oleg Dok
  • 21,109
  • 4
  • 45
  • 54