0
我正在使用SQL Server 2008 R2和C#。SQL锁定批量更新
我将在SQL Server中的一批行与列状态镶有值P。 之后,我检查了多少行已经有状态R,如果少于20行,我将行更新为状态R。 插入和更新时,更多的行正在被添加和更新。
我尝试了多种方式的交易和锁定,但仍然是:在激活新批次的时刻,有超过20行的状态为R几毫秒。几毫秒后,它稳定回到20.
有没有人有一个想法,为什么在阵阵锁定似乎不工作? 示例代码,原因,无论您可以在此主题上分享,都可能有用! 谢谢!
以下是我的存储过程:
DECLARE @return BIT
SET @return = -1
DECLARE @previousValue INT
--insert the started orchestration
INSERT INTO torchestrationcontroller WITH (ROWLOCK)
([flowname],[orchestrationid],[status])
VALUES (@FlowName, @OrchestrationID, 'P')
--check settings
DECLARE @maxRunning INT
SELECT @maxRunning = maxinstances
FROM torchestrationflows WITH (NOLOCK)
WHERE [flowname] = @FlowName
--if running is 0, than you can pass, no limitation here
IF(@maxRunning = 0)
BEGIN
SET @return = 1
UPDATE torchestrationcontroller WITH(ROWLOCK)
SET [status] = 'R'
WHERE [orchestrationid] = @OrchestrationID
END
ELSE
-- BEGIN
RETRY: -- Label RETRY
BEGIN TRY
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION T1
--else: check how many orchestrations are now running
--start lock table
DECLARE @currentRunning INT
SELECT @currentRunning = Count(*)
FROM torchestrationcontroller WITH (TABLOCKX) --Use an exclusive lock that will be held until the end of the transaction on all data processed by the statement
WHERE [flowname] = @FlowName
AND [status] = 'R'
--CASE
IF(@currentRunning < @maxRunning)
BEGIN
-- less orchestrations are running than allowed
SET @return = 1
UPDATE torchestrationcontroller WITH(TABLOCKX)
SET [status] = 'R'
WHERE [orchestrationid] = @OrchestrationID
END
ELSE
-- more or equal orchestrations are running than allowed
SET @return = 0
--end lock table
SELECT @Return
COMMIT TRANSACTION T1
END TRY
BEGIN CATCH
--PRINT 'Rollback Transaction'
ROLLBACK TRANSACTION
IF ERROR_NUMBER() = 1205 -- Deadlock Error Number
BEGIN
WAITFOR DELAY '00:00:00.05' -- Wait for 5 ms
GOTO RETRY -- Go to Label RETRY
END
END CATCH
显然,如果两个线程同时读取计数,然后继续更新,则行数可能会超过20.某些示例代码将有助于诊断确切的情况。 – Andomar
我已经添加了我的代码,希望您可以帮助更多。我认为问题就像你说的,但有没有办法解决这个问题? 我认为ISOLATION LEVEL可能对此有所帮助。 – hhoud
maxRunning = 0的自由通行证似乎很腥...... 50个线程可能会读取它,然后更新50行 – Andomar