0

SQL Server 2008 R2 と C# を使用しています。

Pで設定された列Statusを使用して、SQL Server に行のバッチを挿入しています。その後、ステータスが R である行の数を確認し 20 未満の場合は行をステータス R に更新します。挿入および更新中、より多くの行が常に追加および更新されます。

複数の方法でトランザクションとロックを試みましたが、まだ: 新しいバッチがアクティブ化された時点で、数ミリ秒間Rステータスの行が 20 行以上あります。これらの数ミリ秒の後、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

ツリーストアドプロシージャに分離レベルのシリアル化可能+トランザクションを設定することで修正できました(この問題にとって重要であるとは思わなかったため、そのうちの2つについては触れませんでした)。どうやら、互いに干渉していたのは複数のストアドプロシージャの組み合わせでした。

パフォーマンスを向上させるためのより良い修正方法をご存知の場合は、お知らせください。

于 2012-12-06T14:20:31.953 に答える