0

我正在使用 SQL Server 2008 R2 和 C#。

我在 SQL Server 中插入一批行,其中列Status设置为值P。之后,我检查有多少行已经有状态R,如果少于 20 行,我将该行更新为 Status 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
4

1 回答 1

0

我已经能够通过在树存储过程上设置隔离级别可序列化+事务来修复它(其中两个我没有提到,因为我认为它们对这个问题并不重要)。显然,这是多个相互干扰的存储过程的组合。

如果您知道更好的修复方法,可以给我带来更好的性能,请告诉我!

于 2012-12-06T14:20:31.953 回答