SELECT MAX(value) FROM MyTable WITH (XLOCK, HOLDLOCK)
Should be enough. HOLDLOCK provides serializable semantics, which means that key range locks will be accepted in the range at the end of the index supporting the primary key. XLOCK means that two simultaneous transactions cannot acquire this lock at the same time.
This means that any simultaneous calls to your insert procedure will ultimately be blocked for the duration of the transaction.
A less blocking solution, if you can add a new table, would be to create another table with an identity column and insert into it, as shown below.
CREATE TABLE dbo.Sequence( val int IDENTITY (10000, 1) ) GO CREATE PROC dbo.GetSequence @val AS int OUTPUT AS BEGIN TRAN SAVE TRAN S1 INSERT INTO dbo.Sequence DEFAULT VALUES SET @val=SCOPE_IDENTITY() ROLLBACK TRAN S1 COMMIT TRAN
source share