2013-12-06 3 views
1

Как реализовать шаблон Singleton в хранимой процедуре SQL Server 2005/2008?Шаблон Singleton в хранимой процедуре

Мы хотим, чтобы хранимая процедура возвращает следующее значение из таблицы вызывающего абонента, а затем обновить значение, поэтому следующий вызывающий абонент получает другое значение ...

НО будет время, когда есть много звонящих!

И мы не хотим блокировки/Вопр Тайм-аут

PS. возможно, singleton не ответ ... если нет, как бы вы справились с этим?

+0

Может вам не использовать последовательность? –

+0

Если вы правильно поняли, вы можете использовать что-то вроде этого: «update T set ID + = 1 output inserted.ID» –

+0

Или, если это было предыдущее значение, которое вы хотели, тогда 'update T set ID + = 1 output deleted.ID' –

ответ

0

По определению СИНГЛЕТОН - БЛОКИРОВКА.

Говоря о базах данных, есть так много профессионалов БД, которые боятся, когда вы упоминаете слово «блокировка», но блокировки как таковые не являются проблемой, они являются фундаментальным механизмом для реляционных баз данных.

Вы должны узнать, как работают замки, какие замки существуют и относиться к ним с уважением. Всегда работайте с короткими транзакциями, блокируйте минимальные строки, как можете, работайте с наборами не отдельных строк. Замки становятся проблемой, когда они массивны, и когда они слишком много, и, конечно, когда вы создаете DEADLOCK.

Итак, золотое правило, когда вы должны изменить данные в транзакцию, сначала установите эксклюзивную блокировку (UPDATE), а не общую блокировку (SELECT), это означает, что иногда вам нужно начинать делать ложный LOCK, как в:

BEGIN TRAN 
    UPDATE table 
    set col1 = col1 
    Where Key = @Key 
    ....... 
COMMIT TRAN 

до SQL Server 2012, когда мне нужен серийный я сделал это двумя способами:

создать столбец IDENTITY, поэтому после установки вы можете получить значение с помощью встроенной функции SCOPE_IDENTITY() есть также @@ IDENTITY, но если кто-то создает триггер, который вставляет в другую таблицу с столбец идентичности запускает кошмар.

CREATE TABLE [table] 
(
    Id int IDENTITY(1,1) NOT NULL, 
    col2 .... 
    col3 .... 
) 

Второй вариант заключается в добавлении последовательного столбца обычно в родительской таблице или таблице сделали для него плюс процедуры (вы можете использовать код клиента), чтобы получить серийный номер:

--IF YOU CREATE A SERIAL HERE YOU'LL SPENT SOME SPACE, 
--BUT IT WILL KEEP YOUR BLOCKINGS VERY LOW 
CREATE TABLE Parent 
(
    Id, 
    ChildSerial int not null, 
    col2 ... 
    col3 ... 
    CONSTRAINT PK_Parent PRIMARY KEY (Id) 
) 
GO 

--NAMED CONSTRAINT Auto names are random (avoid them) 
ALTER TABLE Parent 
    ADD CONSTRAINT Parent_DF_ChildSerial DEFAULT(0) FOR ChildSerial; 
GO 

CREATE TABLE Child 
(
    Id int not null 
    col2.. 
    colN.. 
    --PLUS PRIMARY KEY... INDEXES, etc. 
) 

CREATE PROC GetChildId 
(
    @PatentId  int 
    @ChildSerial int output --To use the proc from another proc 
) 
As 
Begin 

    BEGIN TRAN 
     --YOU START WITH A LOCK, SO YOU'LL NEVER GET A DEADLOCK 
     --NOR A FAKE SERIAL (Two clients with the same number) 
     UPDATE Parent 
     SET ChildSerial = ChildSerial + 1 
     WHERE Id = @PatentId 

     If @@error != 0 
      Begin 
      SELECT @ChildSerial = -1 
      SELECT @ChildSerial 
      ROLLBACK TRAN 
      RETURN 
     End 

     SELECT @ChildSerial = ChildSerial 
     FROM Parent 
     WHERE Id = @PatentId 

    COMMIT TRAN 

    SELECT @ChildSerial --To Use the proc easily from a program 

End 
Go 
Смежные вопросы