Превышены системные ресурсы OleDbException
Следующий код выполняет простую команду вставки. Если он вызывается 2000 раз подряд (для вставки 2000 строк), генерируется OleDbException с message = "System Resources Exceeded". Есть ли что-то еще, что я должен сделать, чтобы освободить ресурсы?
using (OleDbConnection conn = new OleDbConnection(connectionString))
using (OleDbCommand cmd = new OleDbCommand(commandText, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
5 ответов
Ошибка превышения системных ресурсов не из-за управляемого кода, а из-за того, что вы убиваете свою базу данных (JET?)
Вы открываете путь ко многим связям, способ быстро...
Несколько советов:
- Избегайте обращений, не открывая новое соединение для каждой отдельной команды, и выполняйте вставки, используя одно соединение.
- Убедитесь, что пул соединений с базой данных работает (не уверен, что это работает с соединениями OLEDB).
- Подумайте об использовании более оптимизированного способа вставки данных.
Вы пробовали это?
using (OleDBConnection conn = new OleDBConnection(connstr))
{
while (IHaveData)
{
using (OldDBCommand cmd = new OldDBCommand())
{
cmd.Connection = conn;
cmd.ExecuteScalar();
}
}
}
Я протестировал этот код с базой данных Access 2007 без исключений (я поднялся до 13000 вставок).
Тем не менее, я заметил, что это ужасно медленно, так как вы каждый раз создаете соединение. Если вы поместите "using(connection)" вне цикла, это будет происходить намного быстрее.
Я не уверен в специфике, но я столкнулся с подобной проблемой. Мы используем базу данных Access с IIS для обслуживания наших клиентов. У нас не так много клиентов, но есть много соединений, которые открываются и закрываются в течение одного сеанса. Примерно через неделю работы мы получаем ту же ошибку, и все попытки подключения терпят неудачу. Чтобы исправить проблему, нам нужно было только перезапустить рабочие процессы.
После некоторых исследований я обнаружил (конечно), что Access не работает хорошо в этой среде. Ресурсы не освобождаются правильно, и со временем исполняемый файл закончится. Чтобы решить эту проблему, мы собираемся перейти к базе данных Oracle. Если это не решит проблему, я буду держать вас в курсе моих выводов.
В дополнение к вышесказанному (подключение к базе данных только один раз), я также хотел бы убедиться, что вы закрываете и удаляете свои подключения. Поскольку большинство объектов в C# управляются из памяти, соединения и потоки не всегда имеют такую роскошь, поэтому, если такие объекты не удаляются, они не гарантируются для очистки. Это имеет дополнительный эффект, оставляя это соединение открытым для жизни вашей программы.
Также, если возможно, я бы посмотрел на использование транзакций. Я не могу сказать, для чего вы используете этот код, но OleDbTransactions полезны при вставке и обновлении многих строк в базе данных.
Это может произойти, потому что вы не утилизируете созданный объект Connection и Command. Всегда удаляйте объект в конце.
OledbCommand.Dispose();