Discussion:
ASP.NET: Ошибка "Cannot open any more tables"
(слишком старое сообщение для ответа)
Dmitriy Kozyrev
2005-11-01 17:03:21 UTC
Permalink
Мы где-то виделись, All?

VS2005 beta2.

В проекте используется источник данных Microsoft Access через OLEDB.
Connection хранится в ApplicationState. Иногда, если часто дергать Reload в
IE, появляется ошибка "Cannot open any more tables". Если немного подождать,
она исчезает.

Данные читаются через OleDbCommand.ExecuteReader(), после чего DataReader'у
делается Close. Достаточно ли этого для освобождения всех ресурсов, занятых
ридером и данными, или нужно принудительно вызывать Dispose или что-либо в
этом роде?

Hа каждую страницу делается не менее одного вызова ExecuteReader, а иногда и
больше десятка.

Microsoft Access используется по той причине, что проект пишется вдвоем, но
MSSQL есть только у меня. Релиз, разумеется, будет работать на MSSQL2000 или
MSSQL2005.

Всего хорошего!
Дмитрий Козырев aka Master aka KLRINFSP
Andrzej Novosiolov
2005-11-02 07:55:04 UTC
Permalink
Post by Dmitriy Kozyrev
VS2005 beta2.
В проекте используется источник данных Microsoft Access через OLEDB.
Connection хранится в ApplicationState. Иногда, если часто дергать Reload в
IE, появляется ошибка "Cannot open any more tables". Если немного подождать,
она исчезает.
Данные читаются через OleDbCommand.ExecuteReader(), после чего DataReader'у
делается Close. Достаточно ли этого для освобождения всех ресурсов, занятых
ридером и данными, или нужно принудительно вызывать Dispose или что-либо в
этом роде?
Hа каждую страницу делается не менее одного вызова ExecuteReader, а иногда и
больше десятка.
Не знаю, изменилось ли что-то в этой области в .NET 2.0, а в .NET 1.1
необходимо вызывать метод Dispose объекта Connection, как только он не
нужен, чтобы вернуть его в connection pool. Не забываешь ли ты это делать?
Оптимальный вариант - в начале обработки страницы создать один Connection,
привязать к нему все Command-объекты, а в Page_Disposing сделать Dispose и
для Connection.

Лучше не хранить Connection ни в ApplicationState, ни в Session, ни в Cache.
Благодаря connection pool, создание connection - дешёвая операция.

Насколько мне известно, вызывать Dispose для DataReader не обязательно.
Close достаточно.

Кроме того, рекомендую установить самый свежий сервис-пак для Jet, если он
ещё не установлен. Помнится, в Jet 4.0 SP6 исправляли ошибку с похожими
симтомами. См.
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q239114&id=Q239114
--
ICQ 8481158, http://www.livejournal.com/users/andrzejn/
Sam Andrews
2005-11-02 08:26:12 UTC
Permalink
Wed Nov 02 2005 09:55, Andrzej Novosiolov wrote to Dmitriy Kozyrev:

AN> Hе знаю, изменилось ли что-то в этой области в .NET 2.0, а в .NET 1.1
AN> необходимо вызывать метод Dispose объекта Connection, как только он не
AN> нужен, чтобы вернуть его в connection pool.
можно подробнее, в чем различие Close и Dispose для connection'а..?
встречал просто разные мнения...

ЗЫ: по поводу Close: Closes the connection to the database. _This is the
preferred method of closing any open connection._
The Close method rolls back any pending transactions. It then releases the
connection to the connection pool, or closes the connection if connection
pooling is disabled.

т.е. по идее Close достаточно...

с уважением, Andrews...
Andrzej Novosiolov
2005-11-02 09:51:35 UTC
Permalink
Post by Sam Andrews
AN> Hе знаю, изменилось ли что-то в этой области в .NET 2.0, а в .NET 1.1
AN> необходимо вызывать метод Dispose объекта Connection, как только он не
AN> нужен, чтобы вернуть его в connection pool.
можно подробнее, в чем различие Close и Dispose для connection'а..?
встречал просто разные мнения...
Я тоже встречал разные мнения. Однажды я встретил письмо от человека,
который столкнулся с проблемами производительности сервера, заменил Close на
Dispose, и проблемы исчезли. Мне этого хватило, чтобы начать везде писать
Dispose. По крайней мере, проблем от этого не возникает.

Вообще же Dispose явно подчищает больше, чем Close. После Close можно
сделать Open и продолжить работать с Connection объектом (хотя
низкоуровневое соединение с базой при этом должно отдаться в пул и взяться
оттуда заново). А после Dispose с объектом уже ничего сделать не получится.
--
ICQ 8481158, http://www.livejournal.com/users/andrzejn/
Dmitriy Kozyrev
2005-11-02 13:34:57 UTC
Permalink
Мы где-то виделись, Andrzej?
Post by Dmitriy Kozyrev
В проекте используется источник данных Microsoft Access через OLEDB.
Connection хранится в ApplicationState. Иногда, если часто дергать Reload
в IE, появляется ошибка "Cannot open any more tables". Если немного
подождать, она исчезает.
Данные читаются через OleDbCommand.ExecuteReader(), после чего
DataReader'у делается Close. Достаточно ли этого для освобождения всех
ресурсов, занятых ридером и данными, или нужно принудительно вызывать
Dispose или что-либо в этом роде?
Hа каждую страницу делается не менее одного вызова ExecuteReader, а иногда
и больше десятка.
AN> Hе знаю, изменилось ли что-то в этой области в .NET 2.0, а в .NET 1.1
AN> необходимо вызывать метод Dispose объекта Connection, как только он не
AN> нужен, чтобы вернуть его в connection pool. Hе забываешь ли ты это
AN> делать? Оптимальный вариант - в начале обработки страницы создать один
AN> Connection, привязать к нему все Command-объекты, а в Page_Disposing
AN> сделать Dispose и для Connection.

Даже так... Дело в том, что я плохо представляю себе, как работает connection
pool, хотя в последнее время слышать о нем приходится все чаще. Поэтому я
как-то побоялся открывать-закрывать коннекшн на каждую страницу и стал хранить
его в Application State. Судя по размерам и содержимому ldb-файла, за все
время работы приложения открывается только один коннекшн, что с точки зрения
логики приложения меня устраивает.

AN> Лучше не хранить Connection ни в ApplicationState, ни в Session, ни в
AN> Cache. Благодаря connection pool, создание connection - дешёвая операция.

Это обнадеживает... Чтобы воспользоваться услугами Connection Pool, нужно
ковырять строку соединения? Будет ли этого достаточно?

AN> Hасколько мне известно, вызывать Dispose для DataReader не обязательно.
AN> Close достаточно.

Понятно, спасибо.

AN> Кроме того, рекомендую установить самый свежий сервис-пак для Jet, если
AN> он ещё не установлен. Помнится, в Jet 4.0 SP6 исправляли ошибку с
AN> похожими симтомами. См.
AN> http://support.microsoft.com/default.aspx?scid=kb;en-us;Q239114&id=Q239114

Значит, это был косяк Jet'а? Хотелось бы это выяснить сейчас, когда проект еще
не переведен на IIS+MSSQL, потому что тогда достигнуть пределов нагруженности
сервера будет значительно сложнее. :)

Всего хорошего!
Дмитрий Козырев aka Master aka KLRINFSP
Andrzej Novosiolov
2005-11-02 14:05:38 UTC
Permalink
On 11/2/2005 15:34, Dmitriy Kozyrev wrote:

AN>> Лучше не хранить Connection ни в ApplicationState, ни в Session, ни в
AN>> Cache. Благодаря connection pool, создание connection - дешёвая операция.
Post by Dmitriy Kozyrev
Это обнадеживает... Чтобы воспользоваться услугами Connection Pool, нужно
ковырять строку соединения? Будет ли этого достаточно?
Специально ничего делать не нужно. Connection Pool создаётся и
поддерживается в ADO.NET автоматически. Для разных провайдеров пул сделан
по-разному: для SQL Server - внутренними средствами .NET Framework, для OLE
DB - через OLE DB session pooling, для ODBC - средствами ODBC Driver
Manager. То есть у каждого свои собственные бантики и шуточки.

При желании этим пулом можно управлять через специальные параметры той же
строки соединения. Посмотри в MSDN по словам "connection pooling".

Один из известных мне подводных камней в SQL Server connection pooling: если
по каким-то причинам серверное соединение в пуле стало не валидным
(например, сервер по своей инициативе прибил ждущее соединение), то пул сам
это не обработает. По крайней мере, не всегда. В этом случае при попытке
открыть Connection ты получишь exception (не помню, какой именно), и только
тогда пул выбросит это соединение из списка. Получая этот exception, нужно
разумное количество раз попробовать переоткрыть соединение, а потом, по
возможности, спросить пользователя: хочет ли он пробовать дальше?
--
ICQ 8481158, http://www.livejournal.com/users/andrzejn/
Artem Prokhorov
2005-11-02 08:04:31 UTC
Permalink
Привет /*Dmitriy*/ /*Kozyrev*/ ! Как живете? Можете?

02-Nov-05 16:34:57, Dmitriy Kozyrev писал к Andrzej Novosiolov
*По* *теме* : Re: ASP.NET: Ошибка "Cannot open any more tables"

AN>> Hе знаю, изменилось ли что-то в этой области в .NET 2.0, а в .NET 1.1
AN>> необходимо вызывать метод Dispose объекта Connection, как только он не
AN>> нужен, чтобы вернуть его в connection pool. Hе забываешь ли ты это
AN>> делать? Оптимальный вариант - в начале обработки страницы создать один
AN>> Connection, привязать к нему все Command-объекты, а в Page_Disposing
AN>> сделать Dispose и для Connection.
DK> Даже так... Дело в том, что я плохо представляю себе, как работает
DK> connection pool, хотя в последнее время слышать о нем приходится все
DK> чаще. Поэтому я как-то побоялся открывать-закрывать коннекшн на
DK> каждую страницу и стал хранить его в Application State. Судя по
DK> размерам и содержимому ldb-файла, за все время работы приложения
DK> открывается только один коннекшн, что с точки зрения логики
DK> приложения меня устраивает.

С connection pool надо поостоpожней. Коpоче это тема отдельного pазговоpа,
но пpи опpеделенной нагpyзке сеpвеpа (т.е. пpи большом количестве наpодy в
секyндy) он начинает глючить и тоpмозить. Hе знаю, может быть в 2.0 .NET
это дело подкpyтили....


-=> Крепко жму горло, искренне Ваш, Артем Прохоров, MCSD <=-
www.sly2m.da.ru ***@mail.ru ICQ:35387403
Dmitriy Kozyrev
2005-11-04 08:17:31 UTC
Permalink
Мы где-то виделись, Artem?

02 Nov 05 11:04:31 в RU.DOTNET Artem Prokhorov -> мне:

AP> С connection pool надо поостоpожней. Коpоче это тема отдельного
AP> pазговоpа, но пpи опpеделенной нагpyзке сеpвеpа (т.е. пpи большом
AP> количестве наpодy в секyндy) он начинает глючить и тоpмозить. Hе знаю,
AP> может быть в 2.0 .NET это дело подкpyтили....

Ждем релиза и начинаем тестировать... :)

Спасибо за предупреждение.

Всего хорошего!
Дмитрий Козырев aka Master aka KLRINFSP
Dmitriy Kozyrev
2005-11-04 08:21:39 UTC
Permalink
Мы где-то виделись, Andrzej?

02 Nov 05 17:05:38 в RU.DOTNET Andrzej Novosiolov -> мне:

AN>>> Лучше не хранить Connection ни в ApplicationState, ни в Session, ни в
AN>>> Cache. Благодаря connection pool, создание connection - дешёвая
AN>>> операция.
Post by Dmitriy Kozyrev
Это обнадеживает... Чтобы воспользоваться услугами Connection Pool, нужно
ковырять строку соединения? Будет ли этого достаточно?
AN> Специально ничего делать не нужно. Connection Pool создаётся и
AN> поддерживается в ADO.NET автоматически. Для разных провайдеров пул сделан
AN> по-разному: для SQL Server - внутренними средствами .NET Framework, для
AN> OLE DB - через OLE DB session pooling, для ODBC - средствами ODBC Driver
AN> Manager. То есть у каждого свои собственные бантики и шуточки.

AN> При желании этим пулом можно управлять через специальные параметры той же
AN> строки соединения. Посмотри в MSDN по словам "connection pooling".

Понятно. Спасибо за помощь.

Кстати, я посмотрел версию msjet40.dll - получается, у меня стоит SP7 для
джета.

Всего хорошего!
Дмитрий Козырев aka Master aka KLRINFSP

Loading...