Я использую базу данных 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 -> добавление более длинных CommandTimeout, добавление более длительного BulkCopyTimeout и перенастройка портов на моем брандмауэре. Все равно не повезло.
Ресурсы, которые я использовал: https://social.msdn.microsoft.com/Forums/en-US/1467d64f-69ae-4c1f-91a2-349fc5d514ae/sqlbulkcopy-fails-with-timeout-expired-error?forum=adodotnetdataproviders
Время ожидания истекло с 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();
}