我有一个简单的getNextID过程,它检索表中的id值并将值递增1.它是在考虑到一些多线程的情况下构建的,但看起来程序中的UPDLOCK实际上并没有它按预期线程安全,我试图了解原因。这个想法是初始选择期间的UPDLOCK会阻止任何其他线程执行该选择,直到程序底部的更新完成为止;然而,这似乎并非如此,因为当两个线程同时触发时我得到重复值。
在阅读了一些其他线程之后,我认为可能发生的事情是UPDLOCK阻止其他线程更新行,但它并不阻止它们执行之前的初始选择更新。因此两个线程都执行相同的select(检索相同的值),然后线程2正在等待线程1更新,然后线程2将该行更新为相同的值。我理解锁正在做什么吗?完成防线程的正确方法是将它全部包装在BEGIN / COMMIT TRANSACTION中吗?
var $select = $("#my_input").selectize();
var selectize = $select[0].selectize;
selectize.setValue(selectize.search("My Default Value").items[0].id);
谢谢!
答案 0 :(得分:1)
另一种方法是稍微使用不同版本的更新查询,并显然将整个事务转换为事务。
CREATE PROCEDURE getNextID
@NextNumber INT OUTPUT
,@id_type VARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @NextValue TABLE (NextNumber int);
BEGIN TRANSACTION;
UPDATE its_id_sequence
SET last_used_number = ISNULL(@NextNumber, 0) + 1
OUTPUT inserted.last_used_number INTO @NextValue(NextNumber)
WHERE id_type = @id_type
SELECT @NextNumber = NextNumber FROM @NextValue
COMMIT TRANSACTION;
END
因此,您首先更新而不读取值,并在更新后获取值并使用它。