Лучший способ сделать сериализуемые обновления таблицы - PullRequest
1 голос
/ 24 февраля 2009

Я давний пользователь Firebird, и у него есть особенность, называемая Генераторами (я думаю, что у Oracle тоже есть и она называется Последовательности). Я новичок в SQL Server, и мне нужно смоделировать ту же функцию. Я не могу использовать поле для идентификации, чтобы решить мою проблему. Мне нужна именованная серия значений, а не уникальный номер для каждой строки.

Больше всего меня беспокоило то, что несколько пользователей одновременно вызывали процедуру и получали дублированные значения, поэтому я решил заблокировать с использованием уровня изоляции SERIALIZABLE.

Итак, я придумал этот код (я использую SQL Server 2005):

CREATE TABLE dbo.GENERATORS
    (
      [NAME] VARCHAR(30) NOT NULL,
      [VALUE] INT,
      CONSTRAINT UNQ_GENERATORS_NAME UNIQUE NONCLUSTERED ( [NAME] )
    )
GO

CREATE PROCEDURE GEN_ID
    (
      @GENERATOR_NAME VARCHAR(30)
    )
AS 
    DECLARE @RETURN_VALUE INT ;
    SET NOCOUNT ON
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION
    UPDATE  GENERATORS
    SET     [VALUE] = [VALUE] + 1
    WHERE   [NAME] = @GENERATOR_NAME
    IF @@ROWCOUNT = 0 
        BEGIN
            INSERT  INTO dbo.GENERATORS ( [NAME], [VALUE] )
            VALUES  ( @GENERATOR_NAME, 1 )
            SET @RETURN_VALUE = 1
        END
    ELSE 
        BEGIN
            SELECT  @RETURN_VALUE = [VALUE]
            FROM    GENERATORS
            WHERE   [NAME] = @GENERATOR_NAME
        END
    COMMIT TRANSACTION
    RETURN @RETURN_VALUE
GO

Итак, мои вопросы:

  • Это хорошее решение?
  • Есть ли лучший способ?

Спасибо.

1 Ответ

2 голосов
/ 24 февраля 2009

Вместо UPDATE и SELECT, чтобы вернуть значение, которое вы только что добавили, вы можете сделать

UPDATE  GENERATORS
SET     @RETURN_VALUE = [VALUE] = [VALUE] + 1
WHERE   [NAME] = @GENERATOR_NAME

, что может устранить необходимость в уровне изоляции

Я бы предпочел возвращать @RETURN_VALUE в качестве параметра OUTPUT, а не в качестве возвращаемого значения, оставляя возвращаемое значение свободным для любого кода ошибки во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...