2016-08-24 74 views
2

私は実際にSQLBulkCopyを使用してデータを送り先に挿入します。このコードは、デッドロックのためにソースSQLサーバーで頻繁に失敗しています。私たちが一括コピーを実行している間、コピーされているテーブルが使用されている可能性があります(私はいくつかの挿入/選択が実行されていることを意味しました)。SQLBulkCopyがデッドロックの原因となる

「TABLOCK」のヒントには問題がありますか?私の理解によると、TABLOCKは共有ロックのみを取得し、問題ではありません。

using (var reader = srcConnection.ExecuteReader($"select * from [{DatabaseName}].[{schemaName}].[{tableName}]")) 
{ 
    const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | 
               SqlBulkCopyOptions.KeepNulls | //Do not replace nulls with defaults in destination 
               SqlBulkCopyOptions.KeepIdentity; 
     //Use the identity values from source, do not generate identities in destination. 

    using (var bcp = new SqlBulkCopy(dstConnection.ConnectionString, bulkCopyOptions)) 
    { 
     const int threeMinutes = 60*3; 

     bcp.BulkCopyTimeout = threeMinutes; //Timeout is for a single batch 
     bcp.BatchSize = 5000; 
     bcp.DestinationTableName = $"[{DestinationDatabaseName}].[{schemaName}].[{tableName}]"; 
     bcp.EnableStreaming = true; 

     foreach (var col in table.Columns.Cast<Column>().Where(c => !c.Computed)) 
     { 
      bcp.ColumnMappings.Add(col.Name, col.Name); 
     } 

     bcp.WriteToServer(reader); 
    } 
} 
+0

を有効にします。この[リンク]を読む(https://social.msdn.microsoft.com/Forums/sqlserver/en-US/932cd26c-53fc-49c0-b082-e7f5f05a9801/deadlock-when-using-sqlbulkcopy-to-concurrently-insert- – Keppy

+0

宛先を同時に入力するのではなく、宛先テーブルがヒープ(つまりインデックスなし)です。デッドロックの起点を超えているのは、ソーステーブルであるが宛先ではないようです。 – SumanKumar

+0

TABLOCKの理解が間違っていると思います。[MSDNのドキュメント](https://msdn.microsoft.com/en-us/library/ms187373.aspx) "* TABLOCK - 取得したロックが適用されることを指定します**テーブルのレベルで**取得されるロックのタイプは実行されるステートメントに依存します** "*(Emphases my)、TABLOCKでの選択は共有ロックのみを行いますが、 )排他的なロックを取る。 –

答えて

2

バルクインサートは、テーブルに行を挿入する必要があります。行を挿入するには、排他ロックが必要です。取得される正確なロックは、並行性モデルによって異なります。

TableLockオプションを指定すると、プロセスは排他テーブルロックを取得しようとします。プロセスが最初に共有テーブルロックを取得し、他のプロセスが行ロックを共有しており、両方のプロセスがロックを排他ロックにアップグレードしようとすると、デッドロックが発生する可能性があります。

デッドロックに関する詳細情報を入手するには、いくつかの方法があり:

関連する問題