Я использую базу данных azure sql (v12) на vm. У меня есть два разных экземпляра баз данных - один для постановки и один для производства. Я пытаюсь захватить данные с этапа и вставить его в производство одним нажатием кнопки. Этот код работает «иногда», что означает случайным образом, что он будет успешным. В противном случае я получаю обратно ошибку:Azure - SqlBulkCopy исключение тайм-аута с истекшим сроком действия
BULK COPY Commit Тип Exception: {0} System.Data.SqlClient.SqlException BULK COPY Сообщение: {0} Время ожидания истекло. Период ожидания истекает до завершения операции или сервер не отвечает. Эта ошибка произошла при попытке подключения к адресату маршрутизации. Продолжительность, затрачиваемая при попытке подключения к исходному серверу, была - [Pre-Login] initialization = 1; квитирование = 17; [Login] initialization = 0; Аутентификация = 0; [Post-Login] complete = 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
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 для достижения того же. В моем случае мне просто нужно было поиграть с настройками, пока не найду лучшие результаты. Также у меня есть логика повтора, которая помогает, но нет серебряной пули ИМХО. – jcwrequests
да обе базы данных находятся на одном и том же сервере. я пытался увеличить свои таймауты до 30 минут, но это просто заставляет их висеть в течение 30 минут ... Стол для копирования сейчас составляет всего 400 строк, поэтому изменение размера партии не повлияло на меня. – c22joe
Является ли процесс запуском кода в той же виртуальной сети? – jcwrequests