Azure - SqlBulkCopy抛出超时过期异常

时间:2016-10-07 19:02:44

标签: c# sql-server azure sqlbulkcopy sqlcommand

我在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,并重新配置防火墙上的端口。仍然没有运气。

我使用的资源:https://social.msdn.microsoft.com/Forums/en-US/1467d64f-69ae-4c1f-91a2-349fc5d514ae/sqlbulkcopy-fails-with-timeout-expired-error?forum=adodotnetdataproviders

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();
}

1 个答案:

答案 0 :(得分:1)

创建SqlBulkCopy实例时,您将传递连接字符串externalConnectionString,从而打开新连接。这可能会导致两个连接尝试修改同一个表时出现死锁问题。

您是否尝试将现有连接externalConnection传递给SqlBulkCopy构造函数而不是连接字符串?