Have you ever wondered why the identity values don't rollback even if
the underlying transaction is rolled back. With a small
example, let's explain
CREATE DATABASE Ident;
-- Create a new table in this database as IdentCol with column c1 as identity
USE Ident
GO
CREATE TABLE IdentCol(c1 intidentity, c2 varchar(10));
-- Lets reset the active transaction log by firing the check point
CHECKPOINT
-- If you want to check what is there in the active transaction log part fire DBCC LOG
DBCCLOG(Ident,4)

-- Begin a transaction insert 1 record into the table and then rollback
BEGIN TRAN T1
INSERT INTO IdentCol VALUES (REPLICATE('a',10));
ROLLBACK TRAN T1
-- Lets see the transaction log again
DBCC LOG(Ident,4)

As (highlighted) can be clearly seen that the generation of the identity column happened outside the transaction (LOP_BEGIN_XACT). This means the identity generation hasn't rolled back even though the insert did. If at the stage we insert 1 row in this table the identity value would be 2
INSERT INTO IdentCol VALUES (REPLICATE('a',10));
SELECT * FROM IdentCol;

CREATE DATABASE Ident;
-- Create a new table in this database as IdentCol with column c1 as identity
USE Ident
GO
CREATE TABLE IdentCol(c1 intidentity, c2 varchar(10));
-- Lets reset the active transaction log by firing the check point
CHECKPOINT
-- If you want to check what is there in the active transaction log part fire DBCC LOG
DBCCLOG(Ident,4)
-- Begin a transaction insert 1 record into the table and then rollback
BEGIN TRAN T1
INSERT INTO IdentCol VALUES (REPLICATE('a',10));
ROLLBACK TRAN T1
-- Lets see the transaction log again
DBCC LOG(Ident,4)
As (highlighted) can be clearly seen that the generation of the identity column happened outside the transaction (LOP_BEGIN_XACT). This means the identity generation hasn't rolled back even though the insert did. If at the stage we insert 1 row in this table the identity value would be 2
INSERT INTO IdentCol VALUES (REPLICATE('a',10));
SELECT * FROM IdentCol;