Попробуйте это:
BEGIN TRAN
INSERT INTO TBLKEY
VALUES((SELECT MAX(ID) + 1 AS NVARCHAR) FROM TBLKEY WITH (UPDLOCK)),'EHSAN')
COMMIT
При выборе максимального идентификатора вы получаете блокировку U на строку. Блокировка U несовместима с блокировкой U, которая будет пытаться получить другой сеанс с тем же запросом, который выполняется одновременно. Только один запрос будет выполнен в данный момент времени. Иды будут в порядке и непрерывны без каких-либо промежутков между ними.
Лучшим решением было бы создать дополнительную таблицу, предназначенную только для хранения текущего или следующего идентификатора, и использовать его вместо максимума.
Вы можете понять разницу, выполнив следующие действия:
Подготовьте таблицу
CREATE TABLE T(id int not null PRIMARY KEY CLUSTERED)
INSERT INTO T VALUES(1)
И затем выполнить следующий запрос в двух различных сеансов один за другим с менее чем 10 секунд друг от друга
BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T
WAITFOR DELAY '0:0:10'
INSERT INTO T VALUES(@idv+1)
COMMIT
Подождите некоторое время, пока оба запроса не будут завершены. Обратите внимание, что один из них преуспел, а другой потерпел неудачу.
Теперь сделайте то же самое с помощью следующего запроса
BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T WITH (UPDLOCK)
WAITFOR DELAY '0:0:5'
INSERT INTO T VALUES(@idv+1)
COMMIT
просмотреть содержимое T
Cleanup Т Стол с DROP TABLE T
вместо +1 пытаются использовать последовательность. –
@DudiKonfino, я не могу использовать идентификатор или последовательность и вычисленное поле, потому что непрерывное число связано с типом продукта, например, это 10001 productA, 20001 productB – Ehsan
Вы можете создать с начала с 10001 и шаг 10000 –