我在vm上使用azure sql数据库(v12)。我有两个不同的数据库实例 - 一个用于登台,一个用于生产。我试图从暂存中获取数据并通过单击按钮将其插入生产中。此代码可以成功运行,有时可以使用'意思是随机的,它会成功的。否则我会收到错误:
BULK COPY提交异常类型:{0} System.Data.SqlClient.SqlException BULK COPY消息:{0}超时已过期。操作完成之前经过的超时时间或服务器没有响应。尝试连接到路由目标时发生此故障。尝试连接到原始服务器时花费的持续时间是 - [Pre-Login] initialization = 1;握手= 17; [登录]初始化= 0;认证= 0; [登录后]完成= 0;
以下是我用来完成此任务的代码,可能存在我没有看到的缺陷。通过转储StringBuilder我可以看到SELECT查询有效并且DELETE查询有效但当我尝试使用SqlBulkCopy复制数据时会抛出错误。任何帮助将不胜感激。我已经通过了一堆MSDN文档但没有运气 - >添加更长的CommandTimeouts,添加更长的BulkCopyTimeout,并重新配置防火墙上的端口。仍然没有运气。
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();
}
答案 0 :(得分:1)
创建SqlBulkCopy实例时,您将传递连接字符串externalConnectionString
,从而打开新连接。这可能会导致两个连接尝试修改同一个表时出现死锁问题。
您是否尝试将现有连接externalConnection
传递给SqlBulkCopy构造函数而不是连接字符串?