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);
}
}
を有効にします。この[リンク]を読む(https://social.msdn.microsoft.com/Forums/sqlserver/en-US/932cd26c-53fc-49c0-b082-e7f5f05a9801/deadlock-when-using-sqlbulkcopy-to-concurrently-insert- – Keppy
宛先を同時に入力するのではなく、宛先テーブルがヒープ(つまりインデックスなし)です。デッドロックの起点を超えているのは、ソーステーブルであるが宛先ではないようです。 – SumanKumar
TABLOCKの理解が間違っていると思います。[MSDNのドキュメント](https://msdn.microsoft.com/en-us/library/ms187373.aspx) "* TABLOCK - 取得したロックが適用されることを指定します**テーブルのレベルで**取得されるロックのタイプは実行されるステートメントに依存します** "*(Emphases my)、TABLOCKでの選択は共有ロックのみを行いますが、 )排他的なロックを取る。 –