hmmmm... There has to be a good solution to this, but i can't find it. Hope you guys can help me.
Application inserts rows into a table. My code has to assign a new primary key to every row. Ideally the primary key is INTEGER, and every new row gets PK = max + 1.
I know i can use GUID's (newid())or IDENTITY for the primary key, but they are my last resort (for many reasons -- don't need to get into them now).
here is the problem
Table:
now there are 2 ways that i can think of to assign PKs:
1. max(pk) + 1 on insert
2. have a separate counter table with max(pk) value which gets +1 on every insert.
both have these problems, but for the description i'll go with # 2 -- counter table
insert procedure:
Load generation script -- runs the procedure 1000 times:
If you run load generation code from 3 different query analyzer windows, you'll get PK violation errors....
If transaction isolation level is raised to repeatable read or serializable, you'll get deadlocks.
What's a good solution?
Application inserts rows into a table. My code has to assign a new primary key to every row. Ideally the primary key is INTEGER, and every new row gets PK = max + 1.
I know i can use GUID's (newid())or IDENTITY for the primary key, but they are my last resort (for many reasons -- don't need to get into them now).
here is the problem
Table:
Code:
CREATE TABLE test (pk INTEGER PRIMARY KEY, v VARCHAR(10))
now there are 2 ways that i can think of to assign PKs:
1. max(pk) + 1 on insert
2. have a separate counter table with max(pk) value which gets +1 on every insert.
both have these problems, but for the description i'll go with # 2 -- counter table
Code:
CREATE TABLE counter(i INTEGER)
INSERT COUNTER SELECT 1
insert procedure:
Code:
CREATE PROCEDURE insert_test @value varchar(10)
AS
DECLARE @i INT
SET NOCOUNT ON
BEGIN TRANSACTION
SELECT @i = i FROM counter
UPDATE counter
SET i = i + 1
INSERT test (pk, v)
SELECT @i, @value
COMMIT TRANSACTION
go
Load generation script -- runs the procedure 1000 times:
Code:
set nocount on
declare @i int
set @i = 1
while @i < 1000
begin
exec insert_test
set @i = @i + 1
end
If you run load generation code from 3 different query analyzer windows, you'll get PK violation errors....
If transaction isolation level is raised to repeatable read or serializable, you'll get deadlocks.
What's a good solution?