Форум: "Основная";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
ВнизОбъекты синхронизации Найти похожие ветки
← →
Loginov Dmitry © (2007-04-19 15:33) [0]Разрабатываю многопоточный DCOM-сервер баз данных по технологии Midas. Никак не выберу подходящий объект синхронизации. Клиент (их число пока не ограничивается) вызывает функции "Старт_Транзакции" и "Завершение_транзакции". Каждый клиент работает со своей базой данных. Однако с одной и той же базой данных могут работать множество клиентов. В ходе транзакции база данных должна находиться в блокированном состоянии, и другие клиенты, работающие с той же самой БД, не могут начать транзакцию, пока первый клиент не завершит свою транзакцию.
Пробовал для синхронизации использовать объект "мьютекс". Не работает. Особенности многопоточного СОМ-сервера таковы, что вызовы "Старт_Транзакции" и "Завершение_транзакции" в общем случае обрабатываются в разных, заранее неизвестных потоках, а мьютекс объект такой, что поток, его захвативший, обязуется его освободить. Однако функция WaitForSingleObject(Mutex, 0) для тестирования факта блокировки хорошо подходит, т.е. из любого потока можно вызвать данную функцию - она не захватить мьютекс после своего выполнения.
Пробовал для синхронизации использовать объект "event". Не работает. У него нет такого ограничения, чтобы поток, его захвативший, должен был его освободить (в данном случае - это плюс). Однако нет возможности проверить факт блокировки с помощью WaitForSingleObject(Event, 0). Эта функция после своего выполнения захватывает Event, если он до этого находился в свободном состоянии. Все это происходит, если при создании мьютекса установить атрибут bManualReset=False. Если же выставить этот атрибут в True, то функцию WaitForSingleObject(Event, 0) можно будет использовать для тестирования факта блокировки, Event она не захватывает. Однако появляется другая проблема: ресур не удается захватить с помощью функции WaitForSingleObject(Event, INFINITE). Она, как и положено, блокирует выполнения потока, пока другой поток этот объект не освободит, но после окончания своей работы Event она не захватывает. Вроде нашел выход из этой ситуации: сразу после этой функции выполнить процедуру ручного захвата Event"a ResetEvent(Event). Если 1 или 2 клиента работают с одной базой, то все прекрасно, а вот если 3 клиента - это провал. Если 2 клиента ожидают освобождения Event"a, который захвачен третьим клиентом, то после того, как он освободит Event, те 2 клиента одновременно выполняют функцию ResetEvent(Event), т.е. корректного захвата ресурса только одним из них не происходит. Поэтому нужен вариант, когда все работает, и функция WaitForSingleObject(Event, INFINITE) сама захватывает Event при своем выполнении.
Так какой же объект синхронизации все-таки выбрать?
← →
clickmaker © (2007-04-19 15:41) [1]
> Клиент (их число пока не ограничивается) вызывает функции
> "Старт_Транзакции" и "Завершение_транзакции".
не клиентское это дело
транзакциями должен управлять сервер. В идеале - именно SQL-сервер
← →
Сергей М. © (2007-04-19 15:52) [2]
> Клиент
Чей клиент какого сервера ?
В 3-хзвенке, как правило, фигурируют 2 клиента: "тонкий" клиент сервера приложений, и сам сервер приложений как клиент некоей СУБД ..
← →
ANB © (2007-04-19 16:08) [3]
> Loginov Dmitry © (19.04.07 15:33)
Ничего не понял - зачем весь этот огород. Практически все СУБД корректно работают с транзакциями и блокировками (некоторые даже слишком активно блокировками пользуются). Аппсервер может спокойно пользоваться этими механизмами не изобретая велосипеды. Если же в качестве СУБД выбрано нечто древнее, то конкурировать с тем же ораклом все равно тяжеловато будет и смысла нету, т.к. для уже практически всех приличных серверов есть халявые варианты.
ИМХО - трехслойка вообще зло и извращение.
← →
Сергей М. © (2007-04-19 16:09) [4]
> ИМХО - трехслойка вообще зло и извращение
Не более чем ИМХО
← →
Loginov Dmitry © (2007-04-19 16:57) [5]Клиентская часть уже давно функционирует. И есть сервер (он работает с Paradox через BDE). Сервер разрабатывался очень давно под один клиент. Потом со временем программисты придумывали блокировки, позволяющие работать с сервером нескольким клиентам одновременно. Про объекты синхронизации те программеры наверное по наслышке знали, и всю блокировку делали через реестр. В общем, даже 2 клиента уже зверски конфликтуют друг с другом. В неотдаленном будущем систему планируется устанавливать к каком-то супермаркете. В нынешнем виде это невозможно.
"Клиент" представляет собой некоего монстра, которого лучше не трогать - развоняется.... Поэтому приходится переделывать сервер так, чтобы клиент подмену не почувствовал. А в нынешнем варианте запуском и остановом транзакций управляет именно клиент. Надеюсь теперь картина более ясная.
Так что же делать с объектами синхронизации?
← →
Loginov Dmitry © (2007-04-19 16:57) [6]> Не более чем ИМХО
+1
← →
clickmaker © (2007-04-19 17:01) [7]
> неотдаленном будущем систему планируется устанавливать к
> каком-то супермаркете
я бы тогда посоветовал полностью логику пересмотреть.
Иначе распугаете покупателями постоянными сбоями на кассах
Еще раз повторю. Не дело это, когда клиент управляет серверными транзакциями.
← →
Сергей М. © (2007-04-19 17:08) [8]
> что же делать с объектами синхронизации?
Да ничего не делать)
Просто выкинуть их нафих за полной ненадобностью и полностью перелопатить логику апп-сервера.
← →
Loginov Dmitry © (2007-04-19 17:12) [9]Потестил семафоры - такая же фигня! Вот блин! Когда не надо - на тебе кучу способов синхронизации. А как потребовалось - нихрена ни один не работает! Абыдна :(
← →
Loginov Dmitry © (2007-04-19 17:15) [10]> я бы тогда посоветовал полностью логику пересмотреть.
> Иначе распугаете покупателями постоянными сбоями на кассах
В этом случает нужно и СУБД нормальную. С нормальными возможностями.
Надеюсь, скоро перейдем всеж-таки на FireBird...
← →
Loginov Dmitry © (2007-04-19 20:11) [11]Ладно. Проверку блокировки можно реализовать и другими способами. Один фик, прога, проверяющая блокировку абсолютно надежной быть не может, поэтому такой подход по большому счету не годится. Но так уж сделан наш "клиент" - прежде чем че-то сделать, проверяет, не блокирована ли база данных.
Всем ответившим спасибо за советы! Обязательно учту в будущем.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.045 c