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?

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


Ega23   (2005-11-11 17:33:00) [1]


> Я к тому, что можно завести массив кверей (по одной на каждый
> вариант апдейта) и каждую пропрепарить. Хотя я наступал
> на грабли с препаре, но это было оракл + одак. Плюс я его
> зря делал.
>


Да уже всё и так нормально.


ANB   (2005-11-11 17:23:00) [2]


> Ega23 ©   (11.11.05 17:17) [51]

Я к тому, что можно завести массив кверей (по одной на каждый вариант апдейта) и каждую пропрепарить. Хотя я наступал на грабли с препаре, но это было оракл + одак. Плюс я его зря делал.


Ega23   (2005-11-11 17:17:00) [3]


> В смысле - количество вариантов запроса - конечное число
> ?


В данный момент - да, но система в любой момент может расшириться.


ANB   (2005-11-11 16:36:00) [4]


> Ega23 ©   (11.11.05 10:49) [49]

В смысле - количество вариантов запроса - конечное число ?


Ega23   (2005-11-11 10:49:00) [5]


> А набор запросов на апдейт фиксированный ?
>


Не понял.


ANB   (2005-11-10 17:47:00) [6]


> Ega23 ©   (10.11.05 16:05) [47]

А набор запросов на апдейт фиксированный ?


Ega23   (2005-11-10 16:05:00) [7]


> если строка SQL не меняется ты ей еще Prepare сделай


меняется.


Slym   (2005-11-10 13:51:00) [8]

Если не требуется возвращать результат запроса то решение: 1! поток с очередью.
В очередь ставишь строку SQL и массив параметров.
или более предпочтительный вариант: поток знает все запросы  (для каждого свой компонент создан) и только параметры подставляй.

в потоке выбираешь очередь и постишь в базу.

Ega23 ©   (09.11.05 15:36) [44]
сократился с 300 мс до 1,5 мс.

если строка SQL не меняется ты ей еще Prepare сделай


WondeRu   (2005-11-09 16:57:00) [9]

Ega23 ©   (08.11.05 17:28) [2]
у дополнительного потока всё-таки СВОЙ коннект, или нет?

свой!


Ega23   (2005-11-09 15:36:00) [10]

В общем так.
По совету sniknik © сделали запрос параметризованным и перешли там, где критично с ADOQuery на ADOCommand и ADODataSet.
Результаты ошеломляющие - такт системы сократился с 300 мс до 1,5 мс. Т.е. в 200 РАЗ!!!

sniknik ©, с меня при встречи много пива! ОГРОМНОЕ СПАСИБО!


root   (2005-11-09 13:57:00) [11]

если одна база  ито RemoteDataModul  там все это реализованно

ядумаю отсюдаплесать надо


Ega23   (2005-11-09 12:25:00) [12]


> Таки выходит, что отдельные потоки на одном коннекте все
> равно ничего не дадут. Т.к. фактически именно коннект будет
> все делать, а остальным потокам, которые встали позже, придется
> ждать тапок. А расчет времени для последовательных апдейтов
> делали ? Если ты сможешь убрать блокировку на одновременный
> апдейт одной таблицы, то для параллельности придется для
> каждого потока заводить свой коннект. А потоки придется
> делать для каждого датчика. Это некузяво, ИМХО.


Ты, по-моему, куда-то не туда полез.
В принцине, sniknik ©   в [34] и [35] посоветовал достаточно красивое решение проблемы. Сейчас будем пробовать.


ANB   (2005-11-09 12:21:00) [13]

Таки выходит, что отдельные потоки на одном коннекте все равно ничего не дадут. Т.к. фактически именно коннект будет все делать, а остальным потокам, которые встали позже, придется ждать тапок. А расчет времени для последовательных апдейтов делали ? Если ты сможешь убрать блокировку на одновременный апдейт одной таблицы, то для параллельности придется для каждого потока заводить свой коннект. А потоки придется делать для каждого датчика. Это некузяво, ИМХО.


Ega23   (2005-11-09 12:11:00) [14]


> Если основной коннект будет делать запросы из той же таблицы,
>  которая апдейтится другим коннектом, то MS SQL сам тебя
> тормознет на время выполнения транзакции обновления (т.е.
>  селект не выполнится пока апдейт не закончится


Низачот. Это всё регламентируется Isolation Level'ом. Я могу и "грязное чтение" делать (собственно, я его и делаю). For Browse которое.


ANB   (2005-11-09 11:31:00) [15]


> Ega23 ©   (09.11.05 09:38) [38]

Такс. Если основной коннект будет делать запросы из той же таблицы, которая апдейтится другим коннектом, то MS SQL сам тебя тормознет на время выполнения транзакции обновления (т.е. селект не выполнится пока апдейт не закончится. Да и другие апдейты будут ждать. Я уже наступал на эту граблю). Я бы посмотрел в сторону кэширования поступления инфы от датчиков, чтобы затора из-за базы не было.


Ega23   (2005-11-09 09:38:00) [16]


> sniknik ©   (09.11.05 01:32) [34]


Это интересно. Спасибо, обязательно попробуем!


Ega23   (2005-11-09 09:37:00) [17]


> А чем смущает "каждому потоку - свой коннект" ?

и

> все давно придумано уже
> создаешь пул потоков в каждом свой коннекшн
> отдаешь запрос пулу и забываешь
> можно пул наращиваемый для масштабируемости


Я ограничен числом коннектов к БД, т.к. MSDE использую.


Polevi   (2005-11-09 08:01:00) [18]

все давно придумано уже
создаешь пул потоков в каждом свой коннекшн
отдаешь запрос пулу и забываешь
можно пул наращиваемый для масштабируемости


sniknik   (2005-11-09 01:43:00) [19]

дополнение
> В реальной же жизни приложение всё-таки ждёт результат выполнения ADOQuery.ExecSQL, что естественно
> сказывается на времени обработки сообщения.
ADOCommand должен отработать немного быстрее... раз уж счет на милисекунды идет... плюс запрос обязательно должен быть параметризированным а не генерироваться на лету.


sniknik   (2005-11-09 01:32:00) [20]

> Под прототипом я имел ввиду добавление дополнительного потока.
> Блин, долго объяснять.
> ...
> Так вот, на update состояния съедается порядка 15 мс. В принципе это нормально, но если запускать этот update
> из основного потока приложения, то эти 15 мс. приложение ждёт ответа. А это уже нехорошо.

так и запускай update из основного потока, тока ставь у команды ExecuteOptions = eoAsyncExecute, тогда основной поток не прервется ожиданием, ADO само выполнит команду в отдельном потоке и твои 15 мс. отработают на фоне основного такта - 100 мс.


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

Наверх

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