我在sql server 2008中存储过程,我的存储过程计算并从表B的列中获取最后一个数字“not primary key”,并在此数字上添加一个(+1)以在下一个语句中使用它相同的存储过程。
我的问题是我有一些重复的数字,我认为这发生在多个用户同时调用存储过程时。这是问题,我该如何解决?
我的代码如下: -
DECLARE @ID AS NVARCHAR(10)
SET @ID = (
SELECT TOP 1 MyNo
FROM Employee
WHERE (
(TypeID = @TypeID) AND
(Year = @Year)
)
ORDER BY ID DESC
)
SET @ID = ISNULL(@ID,0) + 1
INSERT INTO Employee (name,lname,MyNo) VALUES (@name,@lname,@MyNo)
答案 0 :(得分:1)
您可以使用WITH(TABLOCKX,HOLDLOCK)语法在事务持续时间内锁定表:
BEGIN TRANSACTION
DECLARE @ID AS NVARCHAR(10)
SET @ID = (
SELECT TOP 1 MyNo
FROM Employee WITH (TABLOCKX, HOLDLOCK)
WHERE (
(TypeID = @TypeID) AND
(Year = @Year)
)
ORDER BY ID DESC
)
SET @ID = ISNULL(@ID,0) + 1
INSERT INTO Employee (name,lname,MyNo) VALUES (@name,@lname,@MyNo)
COMMIT TRANSACTION
您可以在此处找到有关TABLOCK和TABLOCKX的更多信息: https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table
根据讨论,在这种情况下使用的最佳锁定是:
(UPDLOCK,HOLDLOCK)
答案 1 :(得分:1)
如果您不能使用Identity列或表锁,则另一种方法是使用sp_getapplock
这种机制的优点是,这种锁可用于多个不应同时运行的存储过程,也可用于跨多个表的操作。如果锁定不可用,它还允许处理超时和其他类型的行为。
使用此功能时必须小心,确保正确获取和释放锁定,否则会产生比解决方案更多的问题。