2011-07-28 23 views
0

時には同時に実行される2つのプロセスがあります。SQLの一括挿入と更新 - デッドロックの問題

最初のものは第1の格納Procedure--

まず
UPDATE [CTL].[CTRL].[CTRL_DATA_ERROR_DETAIL] 
      SET [MODIFIED_CONTAINER_SEQUENCE_NUMBER] = @containerSequenceNumber 
       ,[MODIFIED_DATE] = GETDATE() 
       ,[CURRENT_FLAG] = 'N' 
      WHERE [DATA_ERROR_KEY] = @DataErrorKey 
       AND [CURRENT_FLAG] ='Y' 

からコードの--Part

ストアドプロシージャから一括更新され

using (var connection = new SqlConnection(connectionString)) 
      { 
       var bulkCopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.TableLock) 
            {DestinationTableName = "CTRL.CTRL_DATA_ERROR_DETAIL",}; 
       connection.Open(); 
       try 
       { 
        bulkCopy.WriteToServer(errorDetailsDt); 
       } 
       catch (Exception e) 
       { 
        throw new Exception("Error Bulk writing Error Details for Data Stream ID: " + dataStreamId + 
             " Details of Error : " + e.Message); 
       } 
       connection.Close(); 
      } 

バルクインサートでありますプロセスは、(着信レコードの負荷に応じて)少しの時間実行され、第2のproc常にデッドロックの犠牲者になる。

SqlBulkCopyOptions.TableLockは、リソースが解放されるまで2番目のプロセスが待機するように設定する必要があります。

答えて

1

既定では、SqlBulkCopyは排他的なロックを取得しないため、更新処理が開始され、データが挿入されている間にデッドロックが発生します。この問題を回避するには、SqlBulkCopyに、既に提案したように排他的なテーブルロックを取るように指示するか、一括挿入のバッチサイズを適切な数に設定することができます。

私はテーブルロックのアイデアが最善の選択肢だと思います。