【发布时间】:2016-08-24 13:11:43
【问题描述】:
我有以下代码..它实际上使用 SQLBulkCopy 将数据插入目标。由于死锁,此代码在源 SQL 服务器中经常失败。仅供参考,当我们执行批量复制时,正在复制的表可能正在使用(我的意思是一些插入/选择将运行)。
这是导致问题还是“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);
}
}
【问题讨论】:
-
我认为你是对的。阅读此link
-
我们没有同时填充目标,我们的目标表是堆的(即没有索引)。更多死锁的起源似乎是源表而不是目的地。
-
我觉得你对TABLOCK的理解是错误的,from the documentation on the MSDN"TABLOCK - 指定获取的锁是应用在表级别的。获取的锁的类型取决于正在执行的语句。”(强调我的),因此带有 TABLOCK 的选择只会执行共享锁,但插入(就像您正在执行的操作一样)会占用排他锁。
标签: c# sql-server deadlock sqlbulkcopy