SELECT MAX(value)
FROM MyTable
WITH (XLOCK, HOLDLOCK)
Должно быть достаточно. HOLDLOCK
дает сериализуемую семантику, что означает блокировку диапазона ключа для диапазона в конце индекса при резервном копировании первичного ключа. XLOCK
означает, что 2 одновременных транзакции не могут одновременно получить эту блокировку.
Это означает, что любые одновременные абоненты вашей процедуры insert
будут заблокированы на время транзакции.
Менее блокирующим решением, если вы можете добавить новую таблицу, было бы создание другой таблицы со столбцом identity
и вставка в нее, как показано ниже.
CREATE TABLE dbo.Sequence(
val int IDENTITY (10000, 1) /*Seed this at whatever your current max value is*/
)
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 /*Rolls back just as far as the save point to prevent the
sequence table filling up. The id allocated won't be reused*/
COMMIT TRAN