COM Automation for Windows. Многопоточность.

Павел. С
Дата: 20.11.2008 09:46:28
День добрый!

Вот возник вопрос:
Есть БД (10g). Работает на Windows Server 2003.
Там же есть зарегистрированный COM объект (в виде DLL).

Из процедуры PL SQL (назовем ее doit) через пакет ORDCOM вызываются методы этого COM объекта. (т.е. в коде doit присутствуют вызовы ORDCOM.Invoke).

Все работает отлично, когда сессия одна.
А что будет, если сессий станет несколько, и все будут одновременно вызывать процедуру doit, которыя в свою очередь будет вызывать методы COM-объекта?

Вообще возникает целый ряд вопросов:
1) В адресном пространстве какого процесса будет находится код и данные COM объекта?
2) В каком потоке будут вызываться методы COM-объекта?
3) будут ли для каждой новой сессии с Oracle создаваться новый экземляры данных (хотябы) COM объекта при вызове ORDCOM.CreateObject?

Спасибо.
tim128
Дата: 24.02.2009 22:10:31
и все-таки, может кто-нибудь ответить на заданные тут вопросы:
Павел. С
1) В адресном пространстве какого процесса будет находится код и данные COM объекта?
2) В каком потоке будут вызываться методы COM-объекта?
3) будут ли для каждой новой сессии с Oracle создаваться новый экземляры данных (хотябы) COM объекта при вызове ORDCOM.CreateObject?


Elic, спасибо за интересную ссылку, хотя там практически все цитаты из оракловой доки, но изложено гораздо воспринимаемее. Насчет первого вопроса вроде все ясно - в процессе exproc.exe. А вот остальные два вопроса для меня пока загадка
Nikolay Kalmarskiy
Дата: 24.02.2009 22:22:32
оттуда

интерпретатор PL/SQL посылает сообщение прослушивателю (listener) запустить процесс External Procedure Handler(EPH) - extproc.exe для текущей пользовательской сессии;


1 сессия -- 1 процесс. В нём все объекты и будут создаваться.
tim128
Дата: 24.02.2009 22:35:43
Nikolay Kalmarskiy
1 сессия -- 1 процесс. В нём все объекты и будут создаваться.


т.е. при закрытии сессии объект будет уничтожен? Нет, это я уже проверил запустив демку из com\demos\WordDem.sql. После закрытия сессии объект (WORD) остался в памяти. Хотя exproc.exe завершился сразу после окончания вызова. А второй вызов в этой же сессии создал еще один объект. Значит теоретически объект как-то можно использовать и из других сессий. Поэтому вопросы пока остаются открытыми.
Nikolay Kalmarskiy
Дата: 24.02.2009 22:47:51
Это известная бага при работе с COM Automation -- приложение, реализующее интерфейс COM Automation надо закрывать (а winword в локальном адресном пространстве процесса работать не может per design!). Обычно для закрытия приложения используется Application.Quit;

Именно поэтому на сервере COM Automation не держут. Надо выносить через DCOM на отдельную машину, а лучше всего сделать робота, выполняющего задачи на издательском сервере (или сервере приложений) по расписанию. Это стандарт... Странно что вообще COM включили в оракл.
tim128
Дата: 24.02.2009 23:05:45
Подумав немного я решил что поторопился. Nikolay Kalmarskiy имел ввиду 1 сессия - один процесс orawpcom.dll в котором создаются объекты СОМ приложений. Я два раза вызвал CreateObject, создалось два COM объекта, что привело к запуску двух экземпляров WINWORD.EXE. DestroyObject почему-то не уничтожает экземпляр WINWORD, созданный при CreateObject. Закрыв сессию, я уничтожил и экземпляр orawpcom.dll и оба этих объекта, но экземпляры WINWORD.EXE остались в памяти, но поскольку orawpcom.dll уничтожен, то доступа к этим WINWORD.EXE уже нет и они остались бесполезно болтаться в памяти. Из других сессий получить к ним доступ нельзя :(
tim128
Дата: 24.02.2009 23:16:12
Nikolay Kalmarskiy
Это известная бага при работе с COM Automation -- приложение, реализующее интерфейс COM Automation надо закрывать (а winword в локальном адресном пространстве процесса работать не может per design!). Обычно для закрытия приложения используется Application.Quit;

Именно поэтому на сервере COM Automation не держут. Надо выносить через DCOM на отдельную машину, а лучше всего сделать робота, выполняющего задачи на издательском сервере (или сервере приложений) по расписанию. Это стандарт... Странно что вообще COM включили в оракл.


У меня сейчас сделано так - написан сервис на дельфях который висит на отдельном сервере и по команде от оракла (через TCP сокет) вызывает СОМ Automation. Если сокет в настоящий момент используется, то открывается новый тред, в котором создается новый экземпляр COM сервера. Но такой подход вызывает ряд проблем - надо поддерживать Дельфевое приложение которое я писал лет пять назад, СОМ сервер иногда намертво подвисает. А тут еще с переходом на 2008 винды вообще такие приколы открылись, что мне пришла мысль а не переписать ли все под оракл. Естественно, я собирался через DCOM вызывать СОМ сервер удаленно, но вопрос с диспетчеризацией вызовов все равно остается - создавать экземпляр СОМ сервера на каждую сессию оракла нельзя. COM сервер это не ворд и создание экземпляра слишком долгий процесс, его нужно желать только по необходимости. Так вы считаете, что смысла под оракл реализовывать это нет?
Nikolay Kalmarskiy
Дата: 24.02.2009 23:22:44
tim128
Так вы считаете, что смысла под оракл реализовывать это нет?


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

Лучше аккуратно переписать/задокументировать ваш сервис, если есть какие-то проблемы с поддержкой -- их решить и оставить как есть. Всё нормально -- ничего не трогайте.