SQL Server功能 - 防止重复

时间:2011-12-21 03:26:09

标签: sql-server-2005 stored-procedures sql-function record-locking

我有一个SQL Server 2005数据库。 Table A中包含一个标识列以及另一个跨越多行的手动Id列。第二个id列格式为'0000000098',必须是字符串。我无法更改数据类型。

Function A获取最大ID列值,将其递增1,转换为字符串。

我的存储过程获取新ID,然后使用此ID进行多次插入。

如何在更新发生之前阻止两个客户端运行存储过程并获取相同的ID?我可以将表a从读取锁定,直到proc处理完成或者是否有更有效的方法?

如果我可以更改数据类型和/或结构,那将很容易,但我不能。

2 个答案:

答案 0 :(得分:1)

如果您可以将函数表示为单个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在更新锁定下运行,因此没有两个进程可以同时运行它。我认为你根本不需要任何进一步的锁定 - 绝对不是一个完整的锁定....

答案 1 :(得分:0)

是的,您可以锁定表格。你需要做事务中的所有事情,当你第一次阅读表时,你可以使用提示(updlock,holdlock)或甚至(TABLOCKX)进行独占连续锁定