В TSQL, каков наилучший способ создания группы записей в последовательном порядке на поле идентификатора? - PullRequest
3 голосов
/ 14 июля 2010

Я хочу иметь возможность создавать группу записей одновременно и гарантировать, что поле идентификации является непрерывным для группы (без перерывов, потому что кто-то еще входит и создает запись, пока это происходит). Я предполагаю, что какая-то блокировка таблицы будет работать, но я не гуру SQL, поэтому любой совет будет оценен (какой тип блокировки? Любые возможные проблемы? И т. Д.).

Для небольшого фона структура таблицы довольно проста ...

TABLE PropertyCode
(
    Code INT IDENTITY,
    UserID INT
)

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

Ответы [ 3 ]

1 голос
/ 15 июля 2010

Я думаю, что ответ Криса может быть улучшен. В настоящее время он будет выбирать и блокировать все содержимое таблицы.

Если вы используете следующее (и при условии, что у вас есть индекс на Code), он должен просто взять RangeLock, предотвращающий добавление другими транзакциями новых записей с кодами, превышающими максимальный в начале транзакции, но не блокирующий одновременные обновления на существующие записи.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
SELECT Code FROM PropertyCode WHERE Code > IDENT_CURRENT('PropertyCode')
INSERT INTO PropertyCode ..... 
COMMIT TRAN
1 голос
/ 14 июля 2010
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
SELECT * FROM PropertyCode
INSERT INTO PropertyCode ..... 
COMMIT TRAN

Сериализуемый режим изоляции транзакций предотвращает вставки / обновления / удаления, которые влияют на любые выбранные данные, следовательно, SELECT * FROM PropertyCode.

Основная проблема заключается в том, что никакие другие процессы не могут обновлять / вставлять / удалять до тех пор, пока транзакция не будет зафиксирована.

0 голосов
/ 14 июля 2010

Я не уверен, является ли это хорошим ответом или нет, но, похоже, он работает ...

CREATE PROCEDURE ReservePropertyCodes
    @Count INT,
    @UserID INT
AS

DECLARE @i INT

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION

-- Locks the table
SELECT TOP 1 * FROM PropertyCode WITH (TABLOCK)

SET @i = 0
WHILE @i < @Count
BEGIN
    INSERT INTO PropertyCode (UserID) VALUES (@UserID)
    SET @i = @i + 1 
END
COMMIT TRANSACTION

Я все еще могу делать выборки в таблице, но новые вставки блокируются доsproc завершает.

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