Azure - SqlBulkCopy 引发超时过期异常
Posted
技术标签:
【中文标题】Azure - SqlBulkCopy 引发超时过期异常【英文标题】:Azure - SqlBulkCopy throwing a timeout expired exception 【发布时间】:2016-10-07 19:02:44 【问题描述】:我在 vm 上使用 azure sql 数据库 (v12)。我有两个不同的数据库实例——一个用于暂存,一个用于生产。我正在尝试从暂存中获取数据并通过单击按钮将其插入生产中。此代码“有时”成功运行,这意味着它会随机成功。否则我会收到以下错误:
BULK COPY 提交异常类型:0System.Data.SqlClient.SqlException BULK COPY 消息:0超时。在操作完成之前超时时间已过或服务器没有响应。尝试连接到路由目标时发生此故障。尝试连接到原始服务器所花费的持续时间是 - [Pre-Login] 初始化 = 1;握手=17; [登录] 初始化=0;身份验证=0; [登录后] 完成=0;
这是我用来完成这项任务的代码,也许有一个我没有看到的缺陷。通过转储 StringBuilder,我可以看到 SELECT 查询有效,DELETE 查询有效,但是当我尝试使用 SqlBulkCopy 复制数据时抛出错误。任何帮助将不胜感激。我已经浏览了一堆 MSDN 文档,但没有运气 -> 添加更长的 CommandTimeouts,添加更长的 BulkCopyTimeout,并在我的防火墙上重新配置端口。还是没有运气。
我使用过的资源:@987654321@
https://azure.microsoft.com/nb-no/documentation/articles/sql-database-develop-direct-route-ports-adonet-v12/
Timeout expired with SqlBulkCopy
public static object SyncData()
StringBuilder sb = new StringBuilder();
sb.AppendLine("Internal Connection...");
string internalConnectionString = GetConnectionString("ConnectionString");
using (SqlConnection internalConnection = new SqlConnection(internalConnectionString))
internalConnection.Open();
SqlCommand selectCommand = internalConnection.CreateCommand();
selectCommand.CommandTimeout = 180;
try
selectCommand.CommandText = "SELECT * FROM dbo.test";
SqlDataReader reader = selectCommand.ExecuteReader();
sb.AppendLine("External Connection...");
string externalConnectionString = GetConnectionString("ExternalConnectionString");
using (SqlConnection externalConnection = new SqlConnection(externalConnectionString))
externalConnection.Open();
SqlCommand CRUDCommand = externalConnection.CreateCommand();
CRUDCommand.CommandTimeout = 180;
SqlTransaction transaction = externalConnection.BeginTransaction("test");
CRUDCommand.Connection = externalConnection;
CRUDCommand.Transaction = transaction;
try
CRUDCommand.CommandText = "DELETE FROM dbo.test";
sb.AppendLine("DELETE: Number of rows affected = " + CRUDCommand.ExecuteNonQuery());
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(externalConnection, SqlBulkCopyOptions.KeepIdentity, transaction))
try
bulkCopy.DestinationTableName = "dbo.test";
bulkCopy.BatchSize = 100;
bulkCopy.BulkCopyTimeout = 180;
bulkCopy.WriteToServer(reader);
sb.AppendLine("Table data copied successfully");
transaction.Commit();
sb.AppendLine("Transaction committed.");
catch (Exception ex)
sb.AppendLine("BULK COPY Commit Exception Type: 0" + ex.GetType());
sb.AppendLine(" BULK COPY Message: 0" + ex.Message);
try
transaction.Rollback();
catch (Exception ex2)
sb.AppendLine("Rollback Exception Type: 0" + ex2.GetType());
sb.AppendLine(" Message: 0" + ex2.Message);
finally
reader.Close();
catch (Exception ex)
sb.AppendLine("Commit Exception Type: 0" + ex.GetType());
sb.AppendLine(" Message: 0" + ex.Message);
try
transaction.Rollback();
catch (Exception ex2)
sb.AppendLine("Rollback Exception Type: 0" + ex2.GetType());
sb.AppendLine(" Message: 0" + ex2.Message);
catch (Exception ex)
sb.AppendLine("Commit Exception Type: 0" + ex.GetType());
sb.AppendLine(" Message: 0" + ex.Message);
return sb.ToString();
【问题讨论】:
两台服务器是否在同一个虚拟网络上?您是否尝试过尝试超时并可能增加批量大小以减少往返次数?虽然我使用 Dapper、Reactive Extensions 和 Simple.Data 来完成相同的事情,但我有一个类似的过程。在我的情况下,我只需要调整设置,直到找到最佳结果。我也有重试逻辑,但没有灵丹妙药恕我直言。 是的,两个数据库都在同一个 Azure 服务器上。我尝试将超时时间增加到 30 分钟,但这只会让它们挂起 30 分钟......我现在正在复制的表只有 400 行,所以改变批量大小对我没有影响。 进程是否在同一个虚拟网络上运行代码? 【参考方案1】:在创建 SqlBulkCopy 实例时,您将传递连接字符串 externalConnectionString
,从而打开一个新连接。这可能会导致两个连接尝试修改同一个表时出现死锁问题。
您是否尝试将现有连接 externalConnection
传递给 SqlBulkCopy 构造函数而不是连接字符串?
【讨论】:
好主意,我试试看。 你说得对,当我实例化 SqlBulkCopy 时,由于我之前对同一张表的 DELETE 查询,我锁定了该表。我所要做的就是将构造函数更改为using (SqlBulkCopy bulkCopy = new SqlBulkCopy(externalConnection, SqlBulkCopyOptions.KeepIdentity, transaction))
,它运行良好。谢谢!以上是关于Azure - SqlBulkCopy 引发超时过期异常的主要内容,如果未能解决你的问题,请参考以下文章
SqlBulkCopy Azure DataTable 比流式传输更快
Cordova geolocation.getCurrentPosition 在 iPad 上引发超时