Форум: "Базы";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизВопрос про мидас Найти похожие ветки
← →
Alexander_K © (2004-03-10 15:11) [0]Приветствую всех!
Написал программу, с тонким клиентом, которая работает с БД Оракл.
Instancing - Multiple use
Threading model - Apartment
Возникла следующая проблема:
При запуске в нескольких клиентах одновременно довольно длительный запросов эти запросы не выполняются параллельно! Выяснил это запуском одновременно длинного запроса и короткого. По идее если они выполняются параллельно - короткий закончиться быстрее... На самом же деле заканчиваются они в таком же порядке как и запускались...
Получается что каждое подключение не обрабатывается в отдельном витке на сервере приложений. Об этом свидетельствует то, что форма сервера приложений при выполнении запроса повисает и ее нельзя перетащить и т.д.
Народ подскажите как решить данную проблему, хотелось бы чтобы запросы выполнялись параллельно..
← →
Reindeer Moss Eater © (2004-03-10 15:14) [1]Что бы запросы выполялись на Оракле параллельно их надо серверу посылать параллельно.
Из разных сессий и подключений. У тебя это есть?
← →
Reindeer Moss Eater © (2004-03-10 15:15) [2]Ну и сам Оракл не должен быть Personal
← →
Alexander_K © (2004-03-10 15:19) [3]Да мне кажется оракл тут не причем, я пытался и через BDE такое делать, а там есть компонент Session, который это должен по идее разруливать, но результат такой же.
← →
Reindeer Moss Eater © (2004-03-10 15:22) [4]Про Оракл точно наврал. Спутал с локальным IB.
Ну есть TSession и что?
На каждую сессию в сервере приложений должно быть свое подключение к Ораклу.
← →
Alexander_K © (2004-03-10 15:31) [5]Дык я так понимаю при подключении клиента должен создаться отдельный ремот дата модуль
← →
Reindeer Moss Eater © (2004-03-10 15:34) [6]То что ты это понимаешь, еще не гарантирует что он создается.
А то что он не создается - объясняет поведение твоего сервера приложений.
← →
Alexander_K © (2004-03-10 15:34) [7]Дык почему оно не создается-то?
← →
Dimk (2004-03-10 15:44) [8]Это Легко проверить если ( как и во всех примерах про midas ) повеситься на событие OnCreate у RDM ( Remote Data Module )
и увеличивать некий счетчик, значение которого выводить на
главной форме сервера. Когда я делал аналогичные проэкты - видно что RDM-ы создаются для каждого нового клиентского коннекта. У тебя такой счетчик на сервере есть?
← →
Alexander_K © (2004-03-10 15:46) [9]Есть и он меняется
← →
Reindeer Moss Eater © (2004-03-10 15:47) [10]Пофик на RDM"ы.
Хоть миллион их будет.
Нужны отдельные подключения к серверу БД.
Если это BDE, то отдельные экземпляры TDatabase + TSession на каждого клиента сервера приложений.
← →
Dimk (2004-03-10 15:55) [11]А TDatabase И TSession как раз и лежат в RDM - то есть являются
членами класса наследованного от RDM и таким образом они создаются конструктором RDM во время создания RDM :0)
Они лежат в RDM?
← →
Alexander_K © (2004-03-10 16:00) [12]Да конечно TDatabase И TSession лежат в RDM
← →
Nikolay M. © (2004-03-10 16:32) [13]А имена у TSession разные?
← →
Asdor © (2004-03-10 16:57) [14]Как клиенты подключаются к RDM?
← →
Alexander_K © (2004-03-10 17:08) [15]Nikolay M. © (10.03.04 16:32) [13]
Там свойство AutoSessionName стоит true, по этому оно должно имена само генерировать.
Asdor © (10.03.04 16:57) [14]
Через DCOMConnection
← →
Nikolay M. © (2004-03-10 17:20) [16]
> Alexander_K © (10.03.04 17:08) [15]
> Nikolay M. © (10.03.04 16:32) [13]
> Там свойство AutoSessionName стоит true, по этому оно должно
> имена само генерировать.
А TSession на RDM в единственном экземпляре?
← →
Alexander_K © (2004-03-10 17:29) [17]Nikolay M. © (10.03.04 17:20) [16]
Да
← →
Asdor © (2004-03-10 17:31) [18]Имена SessionName, DatabaseName компонентам доступа к данным
надо присваивать в рантайме после их создания,
в AfterConstruction например.
Иначе запросы непонятно через какую Session/Database пойдут.
Возможно через единственную "Default".
← →
Alexander_K © (2004-03-10 17:38) [19]Asdor © (10.03.04 17:31) [18]
Дык в датабазе устанавливается свойство Session не на дефаулт, а на ту которую нужно
← →
Reindeer Moss Eater © (2004-03-10 17:39) [20]Имена SessionName, DatabaseName компонентам доступа к данным
надо присваивать в рантайме после их создания,
Если б то было правда - было бы написано в мануале.
А там написано обратное.
← →
Nikolay M. © (2004-03-10 17:59) [21]
> Alexander_K © (10.03.04 17:29) [17]
Похоже, все правильно. Может, дело в оракле? Я его не знаток :(
Попробуй сделать тестовое приложение и обратиться к Ораклу или DBDEMOS.
Кстати, сервер internal/external?
← →
Alexander_K © (2004-03-10 18:09) [22]Кстати, сервер internal/external?
Не очень понял, но оракл стоит на отдельном сервере
Кстати, если Instancing делать Single use, то на каждого клиента запускается отдельный сервер и тогда конечно же все работает...
Но я все-таки думаю не в оракле это, попробую с дбфкой, посмотрю что получиться
← →
Dimk (2004-03-10 18:12) [23]2 Reindeer Moss Eater
Насчет сессий - в доке как раз и описано:
Set AutoSessionName to control whether or not a unique session name is automatically generated. AutoSessionName is intended to guarantee developers of multi-threaded applications that sessions spawned for each thread are unique at runtime.
When AutoSessionName is false (the default), the application must set the SessionName property for a session component. When AutoSessionName is true, TSession assigns the SessionName property automatically and replicates the session name across the SessionName properties of all dataset components in the data module or form where the session component appears. This allows applications to use sessions in data modules that are replicated over multiple threads. TSession constructs a session name by taking the current value of the Name property and appending an underscore (_) followed by a numeric value. For example, if Name is CustomerSession, then the AutoSessionName might be CustomerSession_2.
А вот чтото про герерацию DataBaseName в рантайме я не видел
Если не сложно - вставьте кусочек... где и для чего.
← →
Alexander_K © (2004-03-10 18:20) [24]Кстати, сервер internal/external?
У меня екстернал
← →
Asdor © (2004-03-10 18:29) [25]Про рантайм я все-таки стормозил наверное :(
покопавшись в DBTables - увидел, что там у TDatabase и TDBDataSet SessionName выставляется в TSession.Notification так что все вроде должно быть с этим нормально (если TSession создается как первый компонент в RDM. если нет - то возможно могут возникнуть проблемы).
Просто я когда писал сервер приложений с RDM"мами после создания RDM сам генерил DatabaseName и выставлял компонетам доступа к данным SessionName и DatabaseName.
← →
Dok_3D © (2004-03-11 11:27) [26]При запуске в нескольких клиентах одновременно довольно длительный запросов эти запросы не выполняются параллельно! Выяснил это запуском одновременно длинного запроса и короткого.
Получается подключение не обрабатывается в отдельном витке ...
Неправильно ты выяснял.
Забудь ты про Oracle. Он то здесь причем?
Сделай на своем сервере приложений два метода:
function Method1
begin
sleep(60000);
end;
function Method2
begin
ShowMessage("Мой мессадж в момент выполния Method1");
end;
Пусть одно клиентское приложение вызовет первый метод.
А второе клиентское приложение в течение минуты пытается вызвать второй.
И сразу все выяснишь, в отдельном, или не в отдельном витке ..
← →
Reindeer Moss Eater © (2004-03-11 11:31) [27]2 Dimk
Apartment Each instance of your remote data module services one request at a time. However, the DLL may handle multiple requests on separate threads if it creates multiple COM objects. Instance data is safe, but you must guard against thread conflicts on global memory. This is the recommended model when using BDE-enabled datasets. (Note that when using BDE-enabled datasets you must add a session component with AutoSessionName set to True.)
← →
Dimk (2004-03-11 12:56) [28]Да, читал...
И тоже думал что это значит что вызов методов каждого COM
делается в отдельном витке - теперь сомневаюсь, так как
проделал эксперимет предложенный мистером Dok_3D :o)
Сделал так:
В интерфейсе RDM сделал метод (Tttttt - это имя класса моего RDM :o) ):
procedure Tttttt.M;
var
F: TForm3;
i: int64;
begin
F := TForm3.Create(nil);
i := 0;
while i <= high(i) do
begin
F.Label1.Caption := Format("%d",[i]);
Application.ProcessMessages;
Inc(i);
end;
F.Free;
end;
Который вызывается из клиентского приложения:
procedure TForm4.Button1Click(Sender: TObject);
begin
DCOMConnection1.AppServer.M;
end;
так вот что выяснилось:
1. Все работает как и сказал Dok_3D.
2. Если же убрать ProcessMessages ( знаю что формы при этом
перерисовываться не буду :o| ) почемуто происходит
умирание и основной формы сервера приложений. А почему же это происходит? Если бы каждый метод M отдельного COM сервера запускался в одельном витке - главный виток ( Main thread ) в котором кстати вызывается Application.Run ( которая обрабатывает сообщения этого основного витка ) не должен бы умирать.
Проверено на программах в которых для того чтобы
основная форма не умирала при запуске длительных не передающих управления ОС алгоритмов ( не вызываются sleep GetMessage и др функции ) я запускл эти алгоритмы в отдельном витке.
Именно из за умирания основного витка - сомневаюсь что
тут все уж так просто: типа каждый COM в своем витке....
← →
sniknik © (2004-03-11 13:06) [29]Dok_3D © (11.03.04 11:27) [26]
неправильный тест
только изза одного, тестируем потоки а используем VCL функцию ShowMessage из модуля диалогов.
нужно из виндов MessageBox использовать она потоконезависима. а ShowMessage исказит результат (кстати ее и без синхронизации вредно запускать).
← →
Alexander_K © (2004-03-11 14:34) [30]Ну что, будут еще какие-нибудь мысли у кого-нибудь?
← →
serge35 (2004-03-11 15:54) [31]Оракл, насколько я знаю, все запросы ставит в очередь.
Запустив один запрос, он запускает другой.
Попробуй запустить одни запрос, который будет работать сутки, и за ним запусти запрос, который будет работать 10 сек.
Второй запрос выполнится раньше первого.
← →
Dimk (2004-03-11 15:59) [32]Вот видоизменил тест немного...
procedure Tttttt.M;
var
i: int64;
begin
MessageBox(0, "AAAAAAAA", "AAAAAAAAA", 0);
i := 0;
while i <= 999999999 do //high(i) do
begin
Inc(i);
end;
MessageBox(0, "BBBBBBB", "BBBBBBBBBB", 0);
end;
Действительно работает параллельно.
При использовании формы ( см предыдущий тест. Кстати причем тут ShowMessage? Форма не диалог и просто создается с свойством Visible == True. ) все както работало не устойчиво и часто
клиент отваливались от сервера, особенно если я запускал их (клиентов) более 2. Основная форма не умирает. Поставил на нее Timer по нему прибаляю счетчик который выводится на главную форму сервера.
Похоже для нормальной многопотоковой работы в RDM годится далеко не все...
Итак... если RDM позволяет многопотоковую работу - то кто же не дает потокам нормально работать? Как в RDM все правильно организовать? Может все проблемы в VCL? Что конкретно в ее структуре мешает?
← →
Alexander_K © (2004-03-11 16:01) [33]serge35 (11.03.04 15:54) [31]
Ты не прав
← →
Reindeer Moss Eater © (2004-03-11 16:03) [34]Чему равно HandleShared у TDatabase ?
← →
Nikolay M. © (2004-03-11 16:05) [35]
> Alexander_K ©
А с дбфками проверил?
← →
Dimk (2004-03-11 16:07) [36]2 serge35
Поверь - это не так! Запросы разных сессий
выполняются параллельно. Даже если предположить
что ты слышал про Oracle MTS - все равно ( если
админ конечно не лох ) существует параметр MTS_MAX_SERVERS
который должен быть достаточно большим чтобы всегда можно было
запустить еще один share server для обработки юзерских запросов если предыдущие уже заняты. Короче маловероятный вариант.
← →
Alexander_K © (2004-03-11 16:08) [37]Reindeer Moss Eater © (11.03.04 16:03) [34]
У меня true
← →
serge35 (2004-03-11 16:08) [38]Ты хочешь сказать, что если запустить один запрос, который отрабатывает сутки, то в течении суток Оракл не выполнит ни одного другого запроса?
← →
Alexander_K © (2004-03-11 16:10) [39]Nikolay M. © (11.03.04 16:05) [35]
Нет еще :(( На работе завал :(
← →
Dimk (2004-03-11 16:11) [40]2 serge35
Извини не врубился сразу...
Выходит что я по поводу оракла как раз с тобой согласен! :o)
← →
serge35 (2004-03-11 16:12) [41]Я знаю, что Oracle Applications, если сервер не может запустить несколько паралельных запросов, то просто добавляется администратор запросов и он их запускает и разруливает.
← →
Reindeer Moss Eater © (2004-03-11 16:12) [42]serge35
Ты сам-то себе не противоречь, да?
Оракл, насколько я знаю, все запросы ставит в очередь.
Как он выполнит второй запрос, если в очереди есть невыполненный первый
← →
Reindeer Moss Eater © (2004-03-11 16:15) [43]Alexander_K © (11.03.04 16:08) [37]
Reindeer Moss Eater © (11.03.04 16:03) [34]
У меня true
Хоть в хелпе и сказано, что д.б. True, но чувствую, что должно быть False.
Иначе все модули данных используют одно и то же подключение.
Отсюда и последовательная обработка запросов
← →
Alexander_K © (2004-03-11 16:15) [44]serge35 (11.03.04 16:12) [41]
Да я тоже не сразу врубился...
← →
Alexander_K © (2004-03-11 16:22) [45]Reindeer Moss Eater © (11.03.04 16:15) [43]
Попробовал, тоже самое
← →
serge35 (2004-03-11 16:25) [46]Оракл ставит запросы в очередь на выполнение.
Сначала запрос обрабатывает оптимизатор, затем только он
начинает выполнятся. После того, как оптимизатор закончил
работу с одним запросом, он берет следующий запрос из очереди.
И как бы вы ни пытались их запустить в паралель, все равно
запросы будут запускаться поочередно.
А то, что более короткий запрос отработал позже более длинного запроса - просто из-за того, что серверу постоянно приходится переключаться от одного запроса к другому, к тому же первый запрос отхватывает для себя больше ресурсов.
← →
Alexander_K © (2004-03-11 16:30) [47]serge35 (11.03.04 16:25) [46]
И что ты хочешь сказать, что если длинный запрос запустить, то никто больше работать не сможет???
← →
sniknik © (2004-03-11 16:30) [48]> Хоть в хелпе и сказано, что д.б. True, но чувствую, что должно быть False.
взять да проверить
(гдето там сверху было что счетчик RDM-ом был реализован)
это уже к автору вопроса, переделай чтобы строку показывало вместо чисел в нее вставьляй Database1.SessionName и проследи какие имена при подключении клиентов у тебя выдает. (может действительно все дефаулт)
← →
serge35 (2004-03-11 16:34) [49]Alexander_K - посмотри мой ответ № 38.
и найди 10 отличий в твоем последнем предложении.
← →
Reindeer Moss Eater © (2004-03-11 16:36) [50]А то, что более короткий запрос отработал позже более длинного запроса - просто из-за того, что серверу постоянно приходится переключаться от одного запроса к другому, к тому же первый запрос отхватывает для себя больше ресурсов.
Собственно я был против термина "очередь".
То что ты тут описал никак очередью называться не может. Это пул запросов.
← →
Alexander_K © (2004-03-11 16:41) [51]sniknik © (11.03.04 16:30) [48]
Как оно может быть дефаулт? Если свойство AutoSessionName стоит true
← →
Dimk (2004-03-11 16:49) [52]2 serge35
Я уже запутался с чем с Тобой согласен а с чем нет :o)
> И как бы вы ни пытались их запустить в паралель, все равно
> запросы будут запускаться поочередно.
Ну а Ты веришь что на виндах на 1 процессоре могут ПАРАЛЛЕЛЬНО
выполняться 2 задачи? :o)
В dedicated режимя для каждой сессии запускается dedicated процесс который и выполняет юзерские запросы.
В MTS есть целая куча shared servers которые берут запросы из очереди и выполняют их. И если их (shared servers) не хватает
они запускаются дополнительно.
И в самом деле если сейчас выполняется запрос который идет несколько часов и еще пройдет несколько часов - то если набрать select sysdate from dual - можно идти курить все это время?
← →
Reindeer Moss Eater © (2004-03-11 16:50) [53]Короче говоря выясняй сколько открывается сессий на оракле при работе твоих клиентов. Гадать на кофейной гуще больше не хочется
← →
Dimk (2004-03-11 16:53) [54]2 Alexander_K
А не хило бы проверить всеже действительно...
кто может поручиться что делает Borland там у нас за спиной :o)
← →
serge35 (2004-03-11 17:04) [55]Dimk - читать надо внимательнее.
> запросы будут запускаться поочередно.
а выполняться они будут паралельно.
как их будет выполнять Оракл - это только одному известно.
← →
Reindeer Moss Eater © (2004-03-11 17:06) [56]Ну и смысл тогда глубокомысленных высказываний
"запросы ставятся в очередь"
"И как бы вы ни пытались их запустить в паралель, все равно
запросы будут запускаться поочередно."
с точки зрения клиента Оракла и в контексте ветки????
← →
Reindeer Moss Eater © (2004-03-11 17:09) [57]Тем более, что очереди никакой нет - запросы обрабатываются параллельно.
← →
serge35 (2004-03-11 17:16) [58]С точки зрения клиента нет никакой разницы, как выполняются запросы. Клиент об этом просто ничего не знает. Он отправил
запрос и ждет ответ и все.
У меня есть пара вопросов:
Длина запроса выражается в сантиметрах или в чем-то еще?
и насколько короткий запрос короче длинного?
← →
Vlad © (2004-03-11 17:19) [59]
> Длина запроса выражается в сантиметрах или в чем-то еще?
> и насколько короткий запрос короче длинного?
Вырази в чем тебе угодно. Хочешь во времени обработки запроса сервером, хочешь в количестве ресурсов, как тебе угодно.
К чему этот вопрос ?
← →
serge35 (2004-03-11 17:25) [60]А может в количестве символов в запросе?
← →
Vlad © (2004-03-11 17:34) [61]
> serge35 (11.03.04 17:25) [60]
Может и в количестве символов, смотря в каком контексте.
Вот только читаю ветку и врубиться не могу к чему этот вопрос ?
← →
Reindeer Moss Eater © (2004-03-11 17:38) [62]Он хочет сказать что у первого клиента очень много букв в его запросе, который никак не может поставиться в "очередь"
и поэтому второй клиент курит
← →
Alexander_K © (2004-03-11 17:38) [63]Сделал такую вещь:
На форме сервера поставил листбокс и на онкриейт RDM повесил продцедуру добавляющую в листбокс DatabaseName и SessionName из компонента Database
DatabaseName у меня равно sss
При запусках клиентов получилось:
sss Session1_1
sss Session1_2
sss Session1_3
При запуске клиентов (3 шт) на оракле (судя по спотлайту) появилось 3 сессии.
При запуске запросов с каждого клиента получилось:
Сессия, которую запустил первую, стала активной и стала выполняться, остальные как были inactive так и остались..
← →
Alexander_K © (2004-03-11 17:40) [64]serge35
Хоре флудить да!!! Давай по существу!
← →
serge35 (2004-03-11 17:55) [65]> Сессия, которую запустил первую, стала активной и стала выполняться, остальные как были inactive так и остались..
Наконец-то появилась здравая идея - посмотреть, как же на самом
деле выполняются запросы.
Лично я это и называю очередью - когда один запрос запустился,
остальные ожидают, когда их обработает оптимизатор.
B Oracle Applications есть форма, в которой выведены все запросы и напротив каждого запроса прописан его статус.
Все прекрасно видно, какой запрос в каком состоянии.
Повторяю еще раз:
Запросы запускаются ПОСЛЕДОВАТЕЛЬНО, а выполняются ПАРАЛЕЛЬНО.
Для опыта предлагаю взять запросы которые очень сильно отличаются по "Длине". Допустим, один выполняется час, другой 2 сек.
Ситуация будет выглядеть так: сначала запуститься первый запрос, через некоторое время второй, ну а закончиться первым должен более "Короткий".
Представляю, что творилось бы в бухгалтерии, если бы пользовался такими терминами!
← →
Dimk (2004-03-11 17:59) [66]2 serge35
Не утрируйте... уж не пиарщик ли вы сударь?
Лично я думаю что речь идет о времени выполнения запроса.
Следовательно:
Длинный запрос - тот что выполняется долго.
Короткий запрос - тот что выполняется быстрее длинного в несколько раз, причем
на том же сервере и примерно в то же время.
Думаю что Автор имел в виду тоже, так как это следует из контекста его вопросов.
Итак:
Есть 2 запроса.
Один короткий :o)
Другой длинный.
Если запустить их из, 2 разных задач, сначала длинный а затем короткий, то короткий закончится раньше.
Если же из программы Автора, которая представляет собой
несколько клиентских программ и одного сервера приложений
в котором создаются несколько RDM, по числу клиентских программ,
запускаются эти запросы в той же последовательности - короткий заканчивается после длинного. Это может, конечно говорить о том что запросы выполняются последовательно (в данном случае).
Мной лично было проверено что дело не в сервере приложений. Сервер приложений прекрасно запускает несколько методов разных COM объектор параллельно.
Вообщето когда я делал подобный проект - я не обратил внимания на то что запросы выполняются последовательно так как мои запросы были КОРОТКИМИ ( :o) )
И тема между прочем серьезная и по ответам видно
что другие тоже не обращали внимания на такое обстоятельство.
Уф вот.
← →
Alexander_K © (2004-03-11 18:01) [67]serge35 (11.03.04 17:55) [65]
Так вот короткий как раз и заканчивается после длинного!!!
Собственно в этом-то и вопрос!
← →
Dimk (2004-03-11 18:03) [68]Именно.
На какой версии оракла работаете?
← →
Alexander_K © (2004-03-11 18:03) [69]Dimk (11.03.04 17:59) [66]
Именно это и имеется ввиду! :)
← →
serge35 (2004-03-11 18:04) [70]Сколько времени выполняется длинный запрос?
← →
Dimk (2004-03-11 18:05) [71]Простите :o)
Про версию оракла вопрос был к serge35
← →
Alexander_K © (2004-03-11 18:05) [72]serge35 (11.03.04 18:04) [70]
длинный запрос выполняется примерно 3 минуты
а короткий практически мгновенно
← →
serge35 (2004-03-11 18:15) [73]при такой разнце в росте, Оракл выполнит короткий запрос быстрее, чем длинный, если получит их одновременно. Это однозначно.
Значит Оракл получает второй запрос только после того, как выполнит первый. Отсюда вывод: проблема не в оракле, а в том диспетчере, который отправляет запросы на оракл.
← →
Dimk (2004-03-11 18:18) [74]Ну наконец - то :o)
← →
serge35 (2004-03-11 18:24) [75]У меня был проект на scktsrvr.exe, подобных проблем не возникало.
← →
Dimk (2004-03-11 18:29) [76]2 serge35
У меня тоже было на нем - но я уже писал что не придавал значения проверке параллельности работы.
А теперь сомневаюсь что там все было параллельно.
← →
serge35 (2004-03-11 18:34) [77]Может автор сообщения что-то утаивает?
или может он изобрел что-то свое?
← →
Dimk (2004-03-11 18:39) [78]2 serge35
А вот скажи Ты ПРОВЕРЯЛ что у Тебя запросы выполняются
параллельно? Я попытаюсь в свободное время
смоделировать ситуацию и чтобы использовалась не DCOM
а сокет сервер.
← →
roottim (2004-03-11 18:40) [79]и что за запросы ???
дело может быть в блокировке длинным запросом ресурса для короткого...
хотя если короткий это читающий select такого быть не должно...
но всеже запросы б в студию...
← →
Alexander_K © (2004-03-11 18:41) [80]roottim (11.03.04 18:40) [79]
Специально выбрал запросы по разным таблицам, так что тексты здесь не важны
← →
Alexander_K © (2004-03-11 18:42) [81]Да и оба запроса читающие!!!
← →
roottim (2004-03-11 18:49) [82]то-биш выполнение их из 2-х сессий склплас дает нужный результат ?
ежели так, то возвращаемся к мидас серверу
← →
Asdor © (2004-03-11 19:42) [83]2 Alexander_K ©
Про запросы...
Открой 2 SQLExplorer"a
Запусти в одном длинный, в другом короткий запрос - и все узнают,
параллельно ли BDE c Oracle выполняют запросы...
← →
Reindeer Moss Eater © (2004-03-11 22:08) [84]Не надо упрямо повторять явную фигню про последовательное выполнение запросов в РАЗНЫХ СЕССИЯХ.
Нету никакого последовательного выполнения.
Это вам не локальный интербейс.
Если 5 минут назад главбух в своей сессии запустил расчет баланса который продлится всю ночь, а я к серверу подошел только сейчас, то мой select sysdate from dual выполнится сразу.
И не надо упрямо бубнить про последовательную постановку запросов в очередь на выполнение.
У автора вопроса он по твоему ТРИ МИНУТЫ ставится на выполнение?
У меня точно такой же сервер приложений, но без использования RDM, с точно таким же Ораклом обслуживает клиентов в доп.нитках одного процесса ПАРАЛЛЕЛЬНО.
Запросил один клиент услугу требующую 20 сек - получил результат через 20 сек.
Запросил другой клиент в это же время услугу требующую 1 сек - получил результат через 1 сек.
Итак, что мы выяснили:
-RDM"ов у автора несколько.
-Каждый открывает свое подключение к Ораклу.
-Но тем не менее, клиенты сервера приложений обслуживаются последовательно.
У меня лично осталось одно объяснение этому феномену:
Метод Open у всех датасетов во всех RDM вызывается в одной и той же нити.
← →
Michail Dalakov © (2004-03-11 23:00) [85]1.Ctrl+Shift+Esc
Выбираем счетчик потоков и смотрим создается ли новый поток
2.Запускаем OCI Debugger (что то типа MSSQL Profiler) и смотрим, а действительно ли второй запрос попадает на сервер, сразу после первого.
Метод Open у всех датасетов во всех RDM вызывается в одной и той же нити. Reindeer Moss Eater © (11.03.04 22:08) [84]
Так не бывает, для каждого клиента в отдельном потоке на сервере приложений создается обслуживающий COM-объект, поэтому метод
Open вызывается в разных потоках.
Можно, предположить, что имеет место синхронизация потоков,
как она у автора получается надо больше информации, но очевидно,
что один поток ждет завершения другого.
← →
Dimk (2004-03-12 18:36) [86]Не ручаюсь как в других версиях Delphi - но я только что попробовал
на Delphi7 с socket connection и с dcom connection.
Использовал компоненты TDataBase, TSession, TQuery, TProvider
(ну как все и рекомендуется в доке и примерах).
У меня запросы работают параллельно.
Переслал мои тесты (экзешники) Alexander_K. Тоже все пашет.
Разница, правда в том что у Alexander_K Borland C++ Builder v5.
Может там какой глюк? Может патчи какие надо поставить?
Поделитесь ссылочками на последние патчи для C++ Builder пожалуйста :o) С благодарностью приму ссылки на патчи к Delphi 7
← →
Alexander_K © (2004-03-12 19:39) [87]Dimk (12.03.04 18:36) [86]
У меня Borland C++ Builder 6
← →
Alexander_K © (2004-03-15 11:10) [88]Народ! Дайте ссылки на патчи к Borland C++ Builder 6, если они есть... Пожалуйста!
← →
Alexander_K © (2004-03-15 11:10) [89]Народ! Дайте ссылки на патчи к Borland C++ Builder 6, если они есть... Пожалуйста!
← →
Alexander_K © (2004-03-16 10:20) [90]Поставил 4 патч на Borland C++ Builder 6 не помогло...
← →
Alexander_K © (2004-03-16 10:20) [91]Поставил 4 патч на Borland C++ Builder 6 не помогло...
← →
Reindeer Moss Eater © (2004-03-16 10:24) [92]Ты выяснил, кто вызывает методы Open у твоих датасетов ?
← →
Alexander_K © (2004-03-16 17:54) [93]Да я и сам пробовал вызывать, и просто ClientDataSet открывать, чтобы он сам открыл запрос - без разници, все так же.
← →
serge35 (2004-03-17 11:10) [94]Спроси об этом у Си - шников, а то они все считают, что Дельфи - это полное фуфло, а Си - рулеззззззззззззз!!!
← →
Reindeer Moss Eater © (2004-03-17 11:14) [95]Alexander_K © (16.03.04 17:54) [93]
Да я и сам пробовал вызывать, и просто ClientDataSet открывать, чтобы он сам открыл запрос - без разници, все так же.
Так в какой нитке ты это делал сам?
Всегда в одной и той же?
← →
Alexander_K © (2004-03-17 11:39) [96]serge35 (17.03.04 11:10) [94]
Это надумано
Reindeer Moss Eater © (17.03.04 11:14) [95]
Я делал метод у сервера, в который передавался запрос через параметр, а я присваивал его Query и поле этого делал Open.
А в какой ветке оно вызывается - в этом и вопрос!
В делфи похоже вызывается в разных нитках, а как это делается в C++ Builder??
← →
Reindeer Moss Eater © (2004-03-17 11:56) [97]Берем событие датасета. Например BeforeOpen.
Внутри него пишем в лог значение GetCurrentThreadID и узнаем всю правду про то, из каких нитей вызван метод Open у этих самых датасетов
← →
Alexander_K © (2004-03-17 12:14) [98]Только что я сделал такую фигню, но не в момент открытия датасета, а на создание RDM, вставляя данные в листбокс, и получилось что треад один и тот же!
Хотя Instancing - Multiple use
Threading model - Apartment
Почему так?
← →
Reindeer Moss Eater © (2004-03-17 12:27) [99]а на создание RDM
Так ЭрДэЭмы - то наверняка создаются главной ниткой. И на выполнение запросов это не влияет.
Влияет то, из какой нити открываются датасеты.
← →
Alexander_K © (2004-03-17 12:51) [100]Пробовал и непосредственно перед Open() Ставить, то же самое, ID один и тот же!!
← →
Reindeer Moss Eater © (2004-03-17 12:55) [101]Значит методы Open вызываются из одной нити.
Значит пока не выполнится первый Open у первого клиента, не начнется выполняться второй Open у второго клиента.
Вот и все.
← →
Alexander_K © (2004-03-17 12:58) [102]Reindeer Moss Eater © (17.03.04 12:55) [101]
Дык это все понятно! Да почему это так????? Должно же быть в разных потоках!
← →
Reindeer Moss Eater © (2004-03-17 13:00) [103]А я против разве?
← →
Michail Dalakov © (2004-03-17 13:10) [104]Michail Dalakov © (11.03.04 23:00) [85]
1.Ctrl+Shift+Esc
Выбираем счетчик потоков и смотрим создается ли новый поток
← →
Reindeer Moss Eater © (2004-03-17 13:12) [105]Michail Dalakov ©
Уже сто лет назад было выяснено, что у автора N датамодулей и N ниток.
← →
Michail Dalakov © (2004-03-17 13:31) [106]Так не бывает,
как могут Query лежащие в разных потоках открываться в одном потоке.
← →
Reindeer Moss Eater © (2004-03-17 13:36) [107]Начнем с того, что Query ни в каких потоках не лежат.
В потоках выполняется код.
← →
Michail Dalakov © (2004-03-17 13:51) [108]Хорошо уберем слэнг и скажем так,
как могут экземпляры объектов созданные в разных потоках окрываться в одном потоке?
← →
Reindeer Moss Eater © (2004-03-17 14:02) [109]А что этому может помешать?
Поток №1 вызвал конструктор
Поток №2 присвоил значения свойствам
Поток №3 присвоил значения параметрам
Поток №4 вызвал метод Open
Поток №5 проскроллил датасет с первой записи до десятой
Поток №6 проскроллил датасет с десятой записи до последней
Поток №7 закрыл датасет
Поток №8 вызвал деструктор.
Что невозможного или незаконного в этом?
← →
Alexander_K © (2004-03-17 14:03) [110]Michail Dalakov © (17.03.04 13:51) [108]
Так вот в этом-то и вопрос, почему Borland C++ Builder 6 создает все в одном потоке?
← →
Reindeer Moss Eater © (2004-03-17 14:14) [111]В скольких потоках созданы датамодули и датасеты - рояли не играет.
Важно в каких потоках вызываются методы Open.
Возможно там просто synchronize для этого используется, я не знаю, - тогда все Open идут из одного потока. Главного.
← →
Reindeer Moss Eater © (2004-03-17 14:21) [112]В скольких потоках созданы датамодули и датасеты - рояли не играет.
Важно в каких потоках вызываются методы Open.
Возможно там просто synchronize для этого используется, я не знаю, - тогда все Open идут из одного потока. Главного.
← →
Michail Dalakov © (2004-03-17 14:36) [113]To Reindeer Moss Eater c (17.03.04 14:02) [109]
Вопрос не в том возможно это или нет в принципе, вопрос в том, что это абсурд для данного конкретного случая
На каждое клиентское приложение в отдельных потоках на сервере создаются COM-объекты, каждое из клиентских приложений вызывает метод COM-объекта, который в конечном счете приводит к открытию набора данных,
где в данном случае по твоему должен открываться набор данных?
← →
Michail Dalakov © (2004-03-17 14:36) [114]To Reindeer Moss Eater c (17.03.04 14:02) [109]
Вопрос не в том возможно это или нет в принципе, вопрос в том, что это абсурд для данного конкретного случая
На каждое клиентское приложение в отдельных потоках на сервере создаются COM-объекты, каждое из клиентских приложений вызывает метод COM-объекта, который в конечном счете приводит к открытию набора данных,
где в данном случае по твоему должен открываться набор данных?
← →
Nikolay M. © (2004-03-17 14:39) [115]А может транзакции есть блокирующие? Не заметил такой мысли в обсуждении выше.
← →
Nikolay M. © (2004-03-17 14:41) [116]А может транзакции есть блокирующие? Не заметил такой мысли в обсуждении выше.
← →
Michail Dalakov © (2004-03-17 15:06) [117]To Alexander_K © (17.03.04 14:03) [110]
To Reindeer Moss Eater © (17.03.04 13:12) [105]
Господа вы как нибудь определитесь в самом деле?
Michail Dalakov © (17.03.04 13:10) [104]
← →
Reindeer Moss Eater © (2004-03-17 15:17) [118]To Alexander_K © (17.03.04 14:03) [110]
To Reindeer Moss Eater © (17.03.04 13:12) [105]
Господа вы как нибудь определитесь в самом деле?
Господин Alexander_K в посте 110 говорил о создании датамодулей одним потоком
А господин Reindeer Moss Eater в посте 105 говорил о том, что они создаются и их все же несколько, а не один.
← →
Michail Dalakov © (2004-03-17 15:18) [119]To Nikolay M. © (17.03.04 14:39) [115]
Оставтье oracle в покое он работает как положенно,
?? А может транзакции есть блокирующие?
это на обычный select * from table? не бывает так.
← →
Alexander_K © (2004-03-17 15:19) [120]Сейчас решил посмотреть из диспетчера задач сколько потоков у меня в сервере
При запуске 1 клиента запустился сервер с 4 потоками
При логине к базе в клиенте на сервере стало 5 потоков
При запуске последующих клиентов (6 штук) потоков на сервере не увеличилось!
Выходит как будь-то single...
Но в проекте у меня стоит
Instancing - Multiple use
Threading model - Apartment
В чем грабли?
← →
Nikolay M. © (2004-03-17 15:33) [121]
> Alexander_K © (17.03.04 15:19) [120]
А счетчик RDM-ов, как где-то в начале советовали, выводишь?
← →
Michail Dalakov © (2004-03-17 15:44) [122]To Alexander_K © (17.03.04 15:19) [120]
Это и следовало ожидать, чудес не бывает
Как создаются RemoteComObject-ы?
← →
Asdor © (2004-03-17 15:46) [123]Какая фабрика классов используется при создании RDM?
Должна использоваться TComponentFactory (в Дельфи так называется, в билдере может CComponentFactory).
Если нет - то грабли возможно здесь...
← →
Michail Dalakov © (2004-03-17 15:47) [124]To Nikolay M. © (17.03.04 15:33) [121]
Причем здесь счетчик RDM-ов, что в одном потоке нельзя создать два RDM-а?
← →
Reindeer Moss Eater © (2004-03-17 16:08) [125]Это и следовало ожидать, чудес не бывает
пост № 84: Выдан диагноз.
посто № 85: реплика "Так не бывает".
И все по-новой ...
← →
Alexander_K © (2004-03-17 16:12) [126]Asdor © (17.03.04 15:46) [123]
В C++ Builder похоже немного по другому как-то, потому что я так пока и не нашел где RDM создается и про TComponentFactory в проекте моем я ничего не нашел...
← →
Asdor © (2004-03-17 16:24) [127]2 Alexander_K © (17.03.04 16:12) [126]
Код в студию (либо мне на почту)...
Либо смотри секцию инициализации модуля (если таковые есть в билдере). Там должно быть что-то в духе TComponentFactory(или какая-то другая Factory)->Create(ComServer, Класс_Твоего_RDM, Class_ID_ТвоегоRDM, ciMultiInstance, tmApartment) ...
← →
Michail Dalakov © (2004-03-17 16:46) [128]To Reindeer Moss Eater © (17.03.04 16:08) [125]
Да, не бывает такое, чтобы для двух RDM созданных в разных потоках метод Open вызывался в одном потоке. (остальное по контексту выше, дабы не повторяться)
C чем ты не согласен?
Что невозможного или незаконного в этом? [109]
Все возможно
← →
Reindeer Moss Eater © (2004-03-17 16:54) [129]А с чем ты был несогласен в 85 посте, в котором ты возражал против поста №84 (против подчеркнутого диагноза в посте №84)
?
← →
Michail Dalakov © (2004-03-17 17:10) [130]Итак, что мы выяснили:
-RDM"ов у автора несколько.
-Каждый открывает свое подключение к Ораклу.
Метод Open у всех датасетов во всех RDM вызывается в одной и той же нити Reindeer Moss Eater © (11.03.04 22:08) [84]
Здесь как и до некоторого момента ты подразумевал, что RDM-ы в разных потоках, а Open в одном,
я с этим сгласиться не мог
← →
Reindeer Moss Eater © (2004-03-17 17:21) [131]Здесь как и до некоторого момента ты подразумевал, что RDM-ы в разных потоках, а Open в одном,
Чё, все по новой?
Нет в потоках никаких эрдээмов.
Нету, понимаешь, или нет?
← →
Reindeer Moss Eater © (2004-03-17 17:34) [132]Главный вывод в посте №84 был подчеркнут.
Только этим могло объясняться поведение сервереа приложений.
А уж сколько потоков там создавали модули данных - пофик.
Ты же берешь, все переворачиваешь задом наперед, и начинаешь с умным видом утверждать, что не бывает такого - несколько потоков создали, а опен вызывается из одного.
Причем сам признал, что технически никаких преград этому нет. Ни малейших.
Вот и все.
← →
Dimk (2004-03-17 17:58) [133]В C++ Builder создание RDM-ов выглядит совсем не так как в делфи. В глубинах я еще не копался. Но есть различия которые видны невооруженным взглядом:
1. Язык ( шутка )
2. В делфи на ходу создается фабрика классов которая ( если я не забыл ) с помощью TComClassManager.AddObjectFactory...
добавляется в некий список. И потом участвует в создании объекта
от которого запрашивается нужный интерфейс...
В Builder вовсю используются шаблонные классы. Такого как TComponentFactory я не нашел. Даже доступ к членам класса RDM (это косноязычное выражение означает лежащие там TQuery TDatabase поля ...) происходит не просто как RDM.Query.... а нужно обращаться к классу, который ... короче вот код
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
class TTest4 : public TCRemoteDataModule
{
__published: // IDE-managed Components
TDatabase *Database1;
TQuery *Query1;
TSession *Session1;
TDataSetProvider *DataSetProvider1;
void __fastcall CRemoteDataModuleCreate(TObject *Sender);
void __fastcall CRemoteDataModuleDestroy(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TTest4(TComponent* Owner);
__published:
};
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
extern PACKAGE TTest4 *Test4;
/////////////////////////////////////////////////////////////////////////////
// TTest4Impl Implements ITest4, default interface of Test4
// ThreadingModel : Apartment
// Dual Interface : TRUE
// Event Support : FALSE
// Default ProgID : test.Test4
// Description : Test4
/////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE TTest4Impl: REMOTEDATAMODULE_IMPL(TTest4Impl, Test4, TTest4, ITest4)
{
public:
BEGIN_COM_MAP(TTest4Impl)
RDMOBJECT_COM_INTERFACE_ENTRIES(ITest4)
END_COM_MAP()
// Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID(_T("test.Test4"));
DECLARE_DESCRIPTION(_T("Test4"));
// Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TRemoteDataModuleRegistrar regObj(GetObjectCLSID(), GetProgID(), GetDescription());
// Disable these flags in order to disable use by socket or web connections.
// Also set other flags to configure the behavior of your application server.
// For more information, see atlmod.h and atlvcl.cpp.
regObj.Singleton = false;
regObj.EnableWeb = true;
regObj.EnableSocket = true;
return regObj.UpdateRegistry(bRegister);
}
// ITest4
protected:
STDMETHOD(Login(BSTR user, BSTR pass));
STDMETHOD(ChSQL(BSTR sql));
};
Так вот класс TTest4 (где лежат Query ...) явно не создается
а создается при конструировании TTest4Impl. И чтобы добраться
до Query1 нужна такая конструкция
STDMETHODIMP TTest4Impl::ChSQL(BSTR sql)
{
m_DataModule->Query1->Close();
m_DataModule->Query1->SQL->Text = sql;
m_DataModule->Query1->Open();
return S_OK;
}
Так что выглядит для Delphi-шника оооочень странно.
А где идет само создание COM классов - копаться и копаться.
В выходные покопаюсь... Конечно если те кто делал многозвенные приложения на C++ Builder не подскажут нам темным ... :o)
← →
Asdor © (2004-03-17 19:40) [134]
> Так что выглядит для Delphi-шника оооочень странно.
Мдя... действительно... а ATL - это вообще жуть. :)
Двухпроходный компилятор и сборка ком-объекта на лету - это конечно круто... только разбираться сложно... :)
Из присланного мне кода пока могу сказать, что можно попробовать решить проблему следующим образом:#define _ATL_APARTMENT_THREADED
в Test4Impl.h.
Если это не поможет - надо глубже копать в эти в шаблоны...
← →
Michail Dalakov © (2004-03-17 19:51) [135]To Reindeer Moss Eater © (17.03.04 17:34) [132]
Главный вывод в посте №84 был подчеркнут.
Метод Open у всех датасетов во всех RDM вызывается в одной и той же нити.
Народ подскажите как решить данную проблему, хотелось бы чтобы запросы выполнялись параллельно..(исходный вопрос)
Если это и только это имелось ввиду, то это извини не вывод это - аксиома (часть 1)
Часть вторая это наличие синхронизации потоков, которая может мешать параллельному выполнению
← →
Michail Dalakov © (2004-03-17 20:00) [136]To Alexander_K ©
А ты попробуй создать сервер на Delphi и подключись клиентом созданном на Builder-e и на оборот а потом ... копать надо
← →
Reindeer Moss Eater © (2004-03-17 20:32) [137]Michail Dalakov ©
Народ подскажите как решить данную проблему, хотелось бы чтобы запросы выполнялись параллельно..(исходный вопрос)
А ты смотрел ответ номер один?
Проблема была локализована еще 135 постов назад.
А ты все : "попробуй муа - муа, попробуй джага-джага"
← →
Michail Dalakov © (2004-03-17 20:54) [138]Alexander_K © (10.03.04 15:11)
Народ подскажите как решить данную проблему, хотелось бы чтобы запросы выполнялись параллельно..(исходный вопрос)
А ты смотрел ответ номер один?[137]
Reindeer Moss Eater © (10.03.04 15:14) [1]
Что бы запросы выполялись на Оракле параллельно их надо серверу посылать параллельно.
Из разных сессий и подключений. У тебя это есть?
Ну и где же локализация проблемы?
В этом утверждении не видно не то что локализации, здесь нет ни малейшего движения, это констатация аксиомы
Никто же не утверждал, что для того чтобы запросы выполнялись паралельно их надо запускать последовательно из одного подключения
← →
Reindeer Moss Eater © (2004-03-17 22:13) [139]Ну и где же локализация проблемы?
В этом утверждении не видно не то что локализации, здесь нет ни малейшего движения, это констатация аксиомы
Боюсь что трудно будет тебе объяснить это.
Раз не замечаешь, что здесь сразу отсекается Оракл как возможный источник проблемы.
Раз не замечаешь, что даны прямые указания на проверку конкретных вещей в сервере приложений.
Попробуй вернуться ко времени поста №1 (к тем исходным данным, что известны на тот момент) и попробуй дать свой ответ.
Никто же не утверждал, что для того чтобы запросы выполнялись паралельно их надо запускать последовательно из одного подключения
Еще раз: не надо брать высказывания, переворачивать их задом наперед, и высасывать из этого мнимые противоречия
← →
Michail Dalakov © (2004-03-18 09:42) [140]Попробуй вернуться ко времени поста №1 (к тем исходным данным, что известны на тот момент) и попробуй дать свой ответ.
Michail Dalakov © (11.03.04 23:00) [85]
Это первый мой пост, который является не просто констатацией аксиом, а прямым руководством к действию, который сразу все и разрешил, я думаю ты спорить с этим не будешь
На хрена нужна была сотня постов с каким то абсурдом про oracle,
про счетчики RDM и т.д., заметь ты даже в 105 посте делаешь совершенно противоположный вывод
Reindeer Moss Eater © (17.03.04 13:12) [105]
Уже сто лет назад было выяснено, что у автора N датамодулей и N ниток.
P.S.
To Reindeer Moss Eater ©
Любишь ты поспорить, даже на пустом месте у нас с тобой почему то возникает спор, я ценю твое мнение, могу заметить, что я нечасто посещаю форум, но из тех не многих раз когда оказывали помощь посты во многих случаях были твоими,
как сейчас помню пару недель назад, суббота, я около часа выдумывал конструкцию BITAND, первый пост в форум, мгновенное решение и ... непередаваемые эмоции, кстати использование BITAND я и раньше встречал в примерах, но на тот момент вспомнить почему-то не мог, а также на тот момент я не мог понять почему столь необходимая ф-ия недокументирована.
... но с одинаковыми инстанциями баз oracle, ты конечно, меня огорчил, просто взяв и попращавшись, в тот момент я действительно по причинам, которые были выше меня не мог сразу привести параметры обеих инстанций, но если интересно то они действительно оказались полностью идентичными.
... я не хочу приводить множества примеров, в которых твои посты были как всегда полезными, очень эмоциональными, с длительным как всегда спором и т.д., могу заметить, что в своем большинстве это имело какой то толк
Думаю необоснованный спор по данному вопросу следует закончить, ну во-первых жалко времени, во-вторых вряд ли кому-то будет какая-то польза, в-третьих вряд ли кому-то это интересно, в четвертых зачем забивать и без того до предела забитую ветку, в пятых ... и т.д.
"Будете у нас на Колыме ... "
best regards
← →
Alexander_K © (2004-03-18 10:07) [141]Asdor © (17.03.04 19:40) [134]
Не помогло :(
← →
Dimk (2004-03-18 10:50) [142]У меня есть предложение к тем у кого есть под рукой
C++ Builder:
Если, конечно, есть время и желание...
Создайте у себя простейший тестовый проектик
как тут уже описывалось, проверьте как у Вас
с параллельностью?
Если вдруг выяснится что у Вас все нормально - надо просто
сравнить проекты Автора и Ваш, если тоже не нормально -
то значит некий глюк на лицо ( или на лице :o) ).
У меня билдера нет под рукой и покопаться с ним смогу не раньше
выходных.
Это бы могло быстрее разрешить загадку :o)
← →
Asdor © (2004-03-18 10:59) [143]2 Alexander_K © (18.03.04 10:07) [141]
Жаль... :(
Почитай книжку Эндрю Трельсена "Модель COM и применение ATL 3.0".
В ней очень хорошо описана работа с этой библиотекой.
Я читал, но давно, и не могу сейчас вспомнить, какие опции/дефайны надо использовать для того, чтобы заставить работать макрос DECLARE_CLASSFACTORY_AUTO_THREAD (как раз он отвечает за создание фабрики классов, которая создает ком-объекты в отдельных апартментах) при сборке твоих ком-объектов.
Вчера было время - я часа три копался в ATL - не нашел... :( может плохо копался... Сегодня, к сожалению, времени нет...
Кстати, присланный проект у меня не компилился - говорит, нужна другая версия билдера (я себе поставил 5 без патчей).
← →
serge35 (2004-03-18 11:03) [144]Есть еще один вариант.
1.Format c:
2.Установка ОС
3.Устанока Oracle
4.Установка C++ Builder
5.Компиляция проекта
6.Запуск проекта
Если ничего не измениться, то
7.Переписать программу.
← →
Dimk (2004-03-18 11:24) [145]2 serge35 (18.03.04 11:03) [144]
1. Format c: из под запущенной виндозы не пройдет :o)
2. Попробуй, кстати проверить :o)
← →
Reindeer Moss Eater © (2004-03-18 11:27) [146]8. Протереть монитор салфеткой Defender
← →
serge35 (2004-03-18 11:29) [147]Тогда п.0. - Загрузиться с дискеты.
Или с другого винта, желательно в DOCе.
С другого винта даже лучше - можно на всякий
случай сбросить на него исходники.
← →
Alexander_K © (2004-03-22 11:38) [148]Ну вроде разобрались.... правда в голове все равно пока каша :)
Правда что бы все работало пришлось править борландовские ошибки в h-файлах :)
← →
Alexander_K © (2004-03-31 17:03) [149]Для решения проблемы пришлось дописывать все самим, в C++ Builder это видимо не реализовано. Пришлось написать свою фабрику и TCAppartmentThread.
Страницы: 1 2 3 4 вся ветка
Форум: "Базы";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
Память: 0.88 MB
Время: 0.105 c