Retryable SQLBulkCopy for SQL Server 2008 R2
本文关键字:2008 R2 Server SQL SQLBulkCopy for Retryable | 更新日期: 2023-09-27 18:04:22
我基本上是从数据库背景和新的。net的东西。如果我的问题听起来很傻,请原谅我。
我在我的代码中使用SqlBulkCopy将数据从一个SQL Server传输到另一个。但由于网络问题,它经常失败。为了避免这种情况,我计划做两件事
-
减少批大小(从5000到1000)并增加超时(从3分钟)。1分钟)
-
实现重试逻辑
我的问题是
- 实现重试的最佳方式是什么,即在表级别还是在批级别(如果可能的话)?
- 我在这里找到了一些弹性SQL Azure框架:https://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50).aspx我们对SQL Server 2008 R2有类似的东西吗?
我使用的示例代码:
private void BulkCopyTable(string schemaName, string tableName)
{using (var reader = srcConnection.ExecuteReader($"select * from [{SourceDBName}].[{schemaName}].[{tableName}]"))
{
const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.KeepNulls |
SqlBulkCopyOptions.KeepIdentity;
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 = $"[{DestinationDB}].[{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);
}
}
}
一个简单的方法是:
- 自行实施批处理。这导致了一个小的低效率,因为
SqlBulkCopy
需要为每个WriteToServer
调用查询元数据。所以批次不要做得太小。实验。 - 插入临时表(不是
#temp
表,而是持久表,以便您可以失去连接并继续)。 - 然后,执行
insert...select
作为最后一步,将行从临时表移动到实际表。
此舞蹈将工作分割为可重试的批次,但就像它是一个事务一样。
如果你不需要原子性,你可以把它留在第(1)步。