I need to check if a unique (not primary key) field is present in a table, if it isn't - insert it:
ID unqiueidentifier, --PK
name varchar(100),
otherID int --Unique
Perhaps using a conditional insert:
DECLARE @OtherID int
INSERT INTO TableA (OtherID)
SELECT @OtherID
WHERE NOT EXIST (SELECT * from TableA where OtherID = @OtherID)
SELECT MainID from TableA where OtherID = @OtherID
Which kind of lock / hint would I require to ensure a concurrent process doesn't insert the same OtherID
in the time between checking and inserting (apparently concurrency is still an issue even in a single statement such as the above).
ref: http://kejser.org/race-condition-when-creating-unique-values/
ref: http://weblogs.sqlteam.com/dang/archive/2007/10/28/Conditional-INSERTUPDATE-Race-Condition.aspx
I have found a lot of information on HOLDLOCK
/ UPDLOCK
. I understand how they could put a hold on SELECTING or UPDATING existing rows. What doesn't make sense is how they can put a lock on INSERTING new rows without basically just locking the entire table - aka TABLOCK
.
How can you lock a row that doesn't exist?! Or would UPDLOCK
just lock the entire table above because you are dong a SELECT *
?
If it does put a lock on the entire table - that seems like it could be very disruptive and bad for scaling?! Perhaps I just enforce a UNIQUE
constraint and allow the occasional exception?
I can't see any good options here?!