Функция SQL Server - предотвращение дублирования - PullRequest
1 голос
/ 21 декабря 2011

У меня есть база данных SQL Server 2005.Table A содержит столбец идентификаторов, а также другой ручной столбец Id, который занимает несколько строк.Второй столбец id имеет формат '0000000098' и должен быть строкой.Я не могу изменить тип данных.

Function A получает максимальное значение столбца ID, увеличивает его на единицу, преобразует в строку.

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

Как я могу запретить двум клиентам запускать хранимую процедуру и получать один и тот же идентификатор до того, как произойдет обновление?Могу ли я заблокировать таблицу a от чтения до тех пор, пока процесс не завершит обработку или есть более эффективный способ?

Если бы я мог изменить тип данных и / или структуру, это было бы легко, но я не могу.

Ответы [ 2 ]

1 голос
/ 21 декабря 2011

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

UPDATE dbo.TableA
SET ManualID = CAST(CAST(ManualID AS INT) + 1 AS VARCHAR(20))
OUTPUT Inserted.ManualID  -- return the newly inserted manual ID for your use
WHERE ..........

Если вам нужно выполнить двухэтапный процесс - SELECT до UPDATE - тогда я бы использовал подсказку WITH (UPDLOCK)на SELECT

DECLARE @OldManualID VARCHAR(20)

BEGIN TRANSACTION

SELECT @OldManualID = ManualID 
FROM dbo.TableA WITH (UPDLOCK)
WHERE........

-- do something with that manual ID

UPDATE dbo.TableA
SET ManualID = (new value of ManualID)
WHERE ..........

COMMIT TRANSACTION

В обоих случаях, так как одиночный UPDATE или SELECT / UDPATE выполняются при блокировке обновления, никакие два процесса не могут запускать это одновременно.Я не думаю, что вам вообще нужна дополнительная блокировка - определенно не полная блокировка таблицы ....

0 голосов
/ 21 декабря 2011

Да, вы можете заблокировать стол.Вам нужно сделать все внутри транзакции, и когда вы впервые читаете таблицу, вы можете установить на нее эксклюзивную непрерывную блокировку с подсказками (updlock, holdlock) или даже (TABLOCKX)

...