Параллелизм SQL Server и сгенерированная последовательность - PullRequest
1 голос
/ 16 марта 2010

Мне нужна последовательность чисел для приложения, и я надеюсь использовать возможности SQL Server для этого. Я создал следующую таблицу и процедуру (в SQL Server 2005):

CREATE TABLE sequences (
  seq_name varchar(50) NOT NULL,
  seq_value int NOT NULL
)

CREATE PROCEDURE nextval
  @seq_name varchar(50)
AS
BEGIN
  DECLARE @seq_value INT

  SET @seq_value = -1

  UPDATE sequences
  SET @seq_value = seq_value = seq_value + 1
  WHERE seq_name = @seq_name

  RETURN @seq_value
END

Я немного обеспокоен тем, что без блокировки таблицы / строки другой запрос может произойти одновременно и в конечном итоге вернуть тот же номер в другой поток или клиент. Это было бы очень плохо, очевидно. Безопасен ли этот дизайн в этом отношении? Могу ли я добавить что-нибудь, что добавит необходимую блокировку, чтобы сделать его безопасным?

Примечание: я знаю о вставках IDENTITY в SQL Server - и это не то, что я ищу в данном конкретном случае. В частности, я не хочу вставлять / удалять строки. По сути, это центральная таблица, которая управляет генератором последовательных чисел для ряда последовательностей.

Ответы [ 2 ]

4 голосов
/ 16 марта 2010

ОБНОВЛЕНИЕ заблокирует строку исключительно, поэтому ваши проблемы параллелизма не обоснованы. Но использование присваивания @variable в операторах UPDATE основано на неопределенном поведении. Это правда, это будет работать, но скорее полагаться на определенное поведение: используйте предложение OUTPUT.

CREATE PROCEDURE nextval
  @seq_name varchar(50)
 , @seq_value INT output
AS
BEGIN
  DECLARE @ot TABLE (seq_value INT)

  UPDATE sequences
  SET seq_value = seq_value + 1
  OUTPUT INSERTED.seq_value INTO @ot
  WHERE seq_name = @seq_name

  SELECT @seq_value = seq_value FROM @ot;
END
0 голосов
/ 04 апреля 2013

Попробуйте этот код:

ALTER PROCEDURE Item_Category_Details


@Item_Category varchar(20)
,@Active VARCHAR(10)

AS 

DECLARE @Item_Category_Code varchar(20)
DECLARE @seqNo AS INTEGER
SELECT @seqNo=ISNULL(Item_Code,0) FROM Seq_Master
SET @seqNo=@seqNo+1
SET @Item_Category_Code=@seqNo

PRINT @Item_Category_Code

INSERT Item_Category_Master
(Item_Category_Code
,Item_Category
,Active
)
VALUES
(
@Item_Category_Code
,@Item_Category
,@Active
)
UPDATE Seq_Master SET Item_Code=@seqNo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...