Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поведение ADOConnection в многопоточном приложении [MSSQL]


Страницы:   1 2 3

Ega23 ©   (2005-11-08 16:46:00) 

Ситуация следующая:
Есть некая система с достаточно большим количеством объектов. У каждого из объектов есть поле Status, и это свойство изменяется в реальном времени по неким событиям (как из пользовательского интерфейса, так, например, и по сетевому событию). Каждый из этих объектов имеет своё отображение в БД.
Теоретически, событие обновления статуса объекта должно происходить по-принципу "плюнул и забыл", т.е. не нужно дожидаться выполнения команды.
В реальной же жизни приложение всё-таки ждёт результат выполнения ADOQuery.ExecSQL, что естественно сказывается на времени обработки сообщения.
После некоторых раздумий было принято решение вынести обновления статусов объектов в отдельный поток. Но тут встала другая проблема: все запросы работают через один ADOConnection, у которого есть свойство State. И которое далеко не всегда только stOpen.
В связи с этим возникает вопрос: как можно обойти данную проблему? Плодить отдельный коннект на каждый поток? Проверять статус ADOConnection во всех потоках? Писать наследника от TADOQuery, где анализировать изменение ADOConnection.State?

В общем, поделитесь мыслями...


isasa   (2005-11-08 17:56:00) [41]

Silver Alex ©   (08.11.05 17:49) [6]
Один коннект на все приложение, один раз открыли при старте и при закрытии программы один раз закрыли.


А если потоков много. ISAPI, например.


Ega23   (2005-11-08 17:56:00) [42]


> 2. А почему-бы не воспользоваться напрямую TADOQuery.ConnectionString,
>  минуя TADOConnection?


Да потому, что это на N запросов получается N коннектов. И на сервере у каждого из них СВОЙ ProcessID.


Silver Alex   (2005-11-08 17:55:00) [43]

>>Ega23 ©   (08.11.05 17:48) [5]

не понял, что такое прототип? обрисуй ситуации конкретней как-то, что за обьекты, что за события. Когда надо вызывать, что записывать в базу или читать. "Connection is busy" когда именно вываливается?не думаю что это TADOConnection, ни разу не встречал.Может сам сервер, хотя утверждать не буду. Надо больше информации


Ega23   (2005-11-08 17:54:00) [44]


> Один коннект на все приложение, один раз открыли при старте
> и при закрытии программы один раз закрыли. Или зачем тогда
> вообще это конекшен.


Вот-вот. Я тоже придерживаюсь такого мнения. Проблема в том, что основное приложение "сосёт" из БД различные выборки, причём достаточно часто. И при этом некая часть этого приложения (тот самый дополнительный поток) работает как "плюнул и забыл".
Сейчас в качестве промежуточного решения проблемы в дополнительном потоке вставлена проверка состояния ADOConnection. Если не stExecuting или stFetching - то пишем данные, иначе - ждём.


ANB   (2005-11-08 17:53:00) [45]


> Ega23 ©   (08.11.05 17:50) [7]

В случае с ораклом при паралельной многопоточке я заводил отдельные сессии для каждого потока. Иначе - жуткие грабли. Для MS SQL я бы сделал так же.


isasa   (2005-11-08 17:53:00) [46]

1. Если инициализация ADO выполнена "по умолчанию" (с CoInitFlags=-1, модель STA), то по поводу потоков трудно что-то сказать.
2. А почему-бы не воспользоваться напрямую TADOQuery.ConnectionString, минуя TADOConnection?


Ega23   (2005-11-08 17:50:00) [47]


> Если нет необходимости работать с транзакциями, то можешь
> вобще без ADOConnecton обойтись. ADOQuery имеет собственный
> ConnectionString
> Или, как вариант, держать коннекцию постоянно открытой.


Коннект и так постоянно открыт. Его никто не закрывает.
А если для каждого ADOQuery свой коннект открывать... Это не есть гуд.


Silver Alex   (2005-11-08 17:49:00) [48]

>>Bronco ©   (08.11.05 17:43) [4]
>>которые открывают-закрывают коннекцию

парни, а вы что открываете-закрываете коннект с базой больше чем один раз? не советую вам так делать.Один коннект на все приложение, один раз открыли при старте и при закрытии программы один раз закрыли. Или зачем тогда вообще это конекшен.


Ega23   (2005-11-08 17:48:00) [49]


> Проблема выглядит какой-то надуманной.Не могу уловить, возможно
> не понял самой задачи.


Проблема в том, что при запуске прототипа было получено исключение, что-то типа: "Connection is busy". Ведь через этот коннект не только команды на обновление состояния идут.


Bronco   (2005-11-08 17:43:00) [50]


> Ega23 ©   (08.11.05 17:28) [2]

Если нет необходимости работать с транзакциями, то можешь вобще без ADOConnecton обойтись. ADOQuery имеет собственный ConnectionString
Или, как вариант, держать коннекцию постоянно открытой.
В противном случае, те участки кода, которые открывают-закрывают коннекцию и работают с данными скорее всего придется защищать с помощью критических секций или чего-то еще.


Silver Alex   (2005-11-08 17:40:00) [51]

а в чем собственно сложность?и при чем здесь вообще ADOConnection.State?  Наверное на каждый обьект(что за обьект, какой именно?) создавать поток и уже в нем(в потоке) производить свои вычисления.А несколько коннектов зачем, тоже не надо? Проблема выглядит какой-то надуманной.Не могу уловить, возможно не понял самой задачи.


Ega23   (2005-11-08 17:28:00) [52]


> WondeRu ©   (08.11.05 17:19) [1]


Не понял: у дополнительного потока всё-таки СВОЙ коннект, или нет? Или на приложение в целом создаётся отдельный поток, в котором идёт всё общение с базой?


WondeRu   (2005-11-08 17:19:00) [53]

Я бы сделал так:
Создается отдельный поток-обработчик, имеющий единственный ADOConnection. В этом потоке создается очередь (хоть TThreadList) сообщений от ваших объектов, которая постоянно (при наличии события в ней) записывается в БД.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо