-
Как лучше реализовать выполнение нескольких запросов из разных потоков к одному SQL-серверу (MSSQL):
при старте программы установить одно соединение с SQL-сервером через ADOConnection, а потом при каждом запросе создавать объект ADOCommand и в свойстве Connection указывать ADOConnection. После работы разрушать объект ADOCommand?
Или есть варианты получше.
-
> Или есть варианты получше.
убрать потоки, включить асинхронный режим.
-
> sniknik (23.07.2010 09:32:01) [1]
С индикацией прогресса по каждому запросу, что бы видеть паралельно запросы
выполняются или последовательно.
-
> Anatoly Podgoretsky © (23.07.10 09:55) [2]
не получится, на клиенте можно получить только прогресс получения данных... выполнение остается "за кадром".
хотя вроде бы поддерживается, т.е. передача запросов на выполнение конечно встанет в очередь (это документировано) также как и получение данных (вроде бы). но вот выполнение будет параллельным (по доке access jet по умолчанию поддерживает до 5 выполняющих потоков. а mssql что хуже что-ли?).
хотя зачем это нужно не понимаю, сам стараюсь не пользоваться такой схемой после ряда тестов, когда выяснил, что несколько последовательно выполненных запросов в сумме требуют меньше времени чем те же самые параллельно. (хотя, с тех пор много времени прошло, и тестил на одно процессорной машине т.что ... может сейчас и есть смысл, но перепроверять не охота)
-
Наверно не полностью написал, что требуется:
через tcp (IdTCPServer) приходит команда, которая после обработки направляется далее, один из вариантов на SQL-сервер. Т.е. поток создаётся обработчиком события IdTCPServer.
Нужно выполнить этот запрос к SQL-серверу через ADOConnection, дождаться ответа и вернуть необходимые данные обратно через tcp (tcp соединение не разрывается).
-
> sniknik (23.07.2010 10:12:03) [3]
Я про него и говорю, поскольку проверять прогресс выполнения задания не
надо, оно гарантировано паралельно для MSSQL серверб а для Акцесс не уверен,
что исполнение и извлечение для одного соединения будет паралельным.
При паралельном исполнение, часто суммарное время больше, но там и цель
другая. Во всяком случае прогресс все покажет, с измерением времени и можно
оба теста прогнать. В итоге будет ясность, а не предположение.
Но я за потоки и отдельные соединения в них.
Я в обычной однопотоковой модели не нахожу места для нескольких
одновременных запросов.
-
> dm37 (23.07.2010 10:28:04) [4]
То есть все таки поток, так зачем же мучаться, создавать условия для ошибок.
Надо просто отдельный ADOConnection на каждое соединение.
-
> dm37 (23.07.2010 10:28:04) [4]
У меня подобная схема с NNTP сервером, 14 паралельных запросов к SQL
серверу, создают ровную 100 процентную нагрузку на 4 ядерный процессор, в
течение нескольких секунд. Данные в потоке поступают с веб сервера, далее на
SQL, далее клиенту NNTP - необязательная часть.
Каждый поток абсолютно изолирован от других и от основного потока.
-
> dm37 (23.07.10 10:28) [4]
Для начала стоит прочитать раздел в "Руководстве для разработчика" о веб-сервисах.
PS. Любители изобретать велосипеды.
-
Сейчас проверил
серверная часть:
один ADOConnection
два ADOCommand используют один ADOConnection
с первого клиента по tcp отправил один долгий запрос (первый поток - ADOCommand1)
а с другого клиента по tcp посылал быстрые запросы (второй поток - ADOCommand2)
быстрые запросы успешно были выполнены, пока выполнялся длинный запрос
Так нельзя делать? будут проблемы?
-
Удалено модератором
-
dm37 (23.07.10 14:06) [9]
У меня в многопоточном приложении были проблемы с одним коннекшеном. Я избавился - просто стал писать в AdoCommand, ConnectionString, а не ссылку на connection по сути это равносильно созданию отдельного AdoConnection.
-
Из собственного опыта - "ручное" управление (ясно что в асинхронном режиме) следует организовывать по принципу "один запрос-одно соединение"
Иначе получались "грабли" (пусть сникник покроет позором - ему не привыкать :))
-
> через tcp (IdTCPServer) приходит команда, которая после
> обработки направляется далее, один из вариантов на SQL-сервер.
> Т.е. поток создаётся обработчиком события IdTCPServer.
> Нужно выполнить этот запрос к SQL-серверу через ADOConnection,
> дождаться ответа и вернуть необходимые данные обратно через
> tcp (tcp соединение не разрывается).
В таком случае однозначно для каждого потока должен быть отдельный ADOConnection. Типичный способ решения - это организовать пул подключений.
Хотя возможно, что такой пул создается автоматически, тогда очень просто: создаешь объект -> подключаешься к БД -> выполняешь запрос -> отключаешься от БД -> уничтожаешь объект.