Обработка тысяч SqlCommands с использованием SqlTransaction вызывает исключение памяти

StackOverflow https://stackoverflow.com//questions/11675430

Вопрос

Я написал специальную функцию репликации в стандартном приложении Windows Forms C# с базой данных SQL Server 2008 Express.По сути, он извлекает набор операторов sql, которые необходимо выполнить для базы данных подписчиков.При полном обновлении может быть выполнено более 200 тысяч операторов, которые необходимо выполнить.

Я обрабатываю эти операторы внутри блока кода, как показано ниже:

using (SqlConnection connection = ConnectionManager.GetConnection())
{
     connection.Open();

     SqlTransaction transaction = connection.BeginTransaction();

     // Process 200k+ Insert/Update/Delete statements using SqlCommands

     transaction.Commit
}

Я обнаружил, что использование памяти моими приложениями остается довольно стабильным и составляет около 40 МБ для первых 30 тысяч операторов.После чего внезапно кажется, что он подскочил примерно до 300 МБ, а затем увеличился, пока я не столкнулся с исключением OutOfMemory.

Возможен ли вообще метод, который я использую, могу ли я обработать такое количество операторов внутри одной транзакции?Я предполагаю, что смогу это сделать.Если есть лучший способ, я бы с удовольствием разместил его здесь.Мне нужно, чтобы это было транзакционным, иначе частичная репликация приведет к повреждению базы данных.

Спасибо.

РЕДАКТИРОВАТЬ:

После перезагрузки компьютера мне удалось выполнить полную репликацию более 200 тысяч.Несмотря на то, что в какой-то момент использование памяти выросло до 1,4 ГБ после завершения репликации, использование памяти снова упало до 40 МБ.Это приводит меня к выводу, что что-то внутри моего цикла, обрабатывающее команды, возможно, вызывает рост памяти.

Это было полезно?

Решение

Ты Disposing ваши формы и одноразовые элементы управления перед закрытием?

Оберните все одноразовые объекты в оператор using.Нажмите здесь для более подробной информации


Не открывайте/закрывайте соединение снова и снова, вместо этого отправляйте данные в базу данных за одну транзакцию.Нажмите здесь для более подробной информации


Тем не менее, ваше приложение занимает слишком много памяти, тогда вам нужен доктор, такой как профилировщик памяти Red Gate Ants.Нажмите здесь, чтобы увидеть более подробную информацию об этом

enter image description here


могу ли я обработать такое количество операторов внутри одной транзакции?

У вас есть варианты ниже, чтобы сделать это...

  1. Массовая вставка и управление записями в Stored Proc.
  2. Подготовить XML и отправьте строку Database.
  3. Отправить только для чтения DataTable на сервере Sql через хранимую процедуру

Пример сохраненной процедуры

Begin Try
    Set NoCount ON
    Set XACT_Abort ON
    Begin TRan
        --Your queries
    Commit Tran

Begin Tran

Begin Catch
    Rollback Tran
End Catch

Убедись в Dispose объекты, когда-то не используемые.


Это должно быть так

using (SqlConnection connection = new SqlConnection())
{
    connection.Open();
    using (SqlTransaction transaction = connection.BeginTransaction())
    {
        transaction.Commit();
    }
}

Вы проверили SqlCommand также?

using (SqlCommand cmd = new SqlCommand())
{
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top