Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Объекты синхронизации


Loginov Dmitry ©   (2007-04-19 15:33:00) 

Разрабатываю многопоточный 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 при своем выполнении.

Так какой же объект синхронизации все-таки выбрать?


Loginov Dmitry   (2007-04-19 20:11:00) [1]

Ладно. Проверку блокировки можно реализовать и другими способами. Один фик, прога, проверяющая блокировку абсолютно надежной быть не может, поэтому такой подход по большому счету не годится. Но так уж сделан наш "клиент" - прежде чем че-то сделать, проверяет, не блокирована ли база данных.

Всем ответившим спасибо за советы! Обязательно учту в будущем.


Loginov Dmitry   (2007-04-19 17:15:00) [2]

> я бы тогда посоветовал полностью логику пересмотреть.
> Иначе распугаете покупателями постоянными сбоями на кассах


В этом случает нужно и СУБД нормальную. С нормальными возможностями.
Надеюсь, скоро перейдем всеж-таки на FireBird...


Loginov Dmitry   (2007-04-19 17:12:00) [3]

Потестил семафоры - такая же фигня! Вот блин! Когда не надо - на тебе кучу способов синхронизации. А как потребовалось - нихрена ни один не работает! Абыдна :(


Сергей М.   (2007-04-19 17:08:00) [4]


> что же делать с объектами синхронизации?


Да ничего не делать)
Просто выкинуть их нафих за полной ненадобностью и полностью перелопатить логику апп-сервера.


clickmaker   (2007-04-19 17:01:00) [5]


> неотдаленном будущем систему планируется устанавливать к
> каком-то супермаркете

я бы тогда посоветовал полностью логику пересмотреть.
Иначе распугаете покупателями постоянными сбоями на кассах

Еще раз повторю. Не дело это, когда клиент управляет серверными транзакциями.


Loginov Dmitry   (2007-04-19 16:57:00) [6]

Клиентская часть уже давно функционирует. И есть сервер (он работает с Paradox через BDE). Сервер разрабатывался очень давно под один клиент. Потом со временем программисты придумывали блокировки, позволяющие работать с сервером нескольким клиентам одновременно. Про объекты синхронизации те программеры наверное по наслышке знали, и всю блокировку делали через реестр. В общем, даже 2 клиента уже зверски конфликтуют друг с другом. В неотдаленном будущем систему планируется устанавливать к каком-то супермаркете. В нынешнем виде это невозможно.
"Клиент" представляет собой некоего монстра, которого лучше не трогать - развоняется.... Поэтому приходится переделывать сервер так, чтобы клиент подмену не почувствовал. А в нынешнем варианте запуском и остановом транзакций управляет именно клиент. Надеюсь теперь картина более ясная.

Так что же делать с объектами синхронизации?


Loginov Dmitry   (2007-04-19 16:57:00) [7]

> Не более чем ИМХО


+1


Сергей М.   (2007-04-19 16:09:00) [8]


> ИМХО - трехслойка вообще зло и извращение


Не более чем ИМХО


ANB   (2007-04-19 16:08:00) [9]


> Loginov Dmitry ©   (19.04.07 15:33)

Ничего не понял - зачем весь этот огород. Практически все СУБД корректно работают с транзакциями и блокировками (некоторые даже слишком активно блокировками пользуются). Аппсервер может спокойно пользоваться этими механизмами не изобретая велосипеды. Если же в качестве СУБД выбрано нечто древнее, то конкурировать с тем же ораклом все равно тяжеловато будет и смысла нету, т.к. для уже практически всех приличных серверов есть халявые варианты.
ИМХО - трехслойка вообще зло и извращение.


Сергей М.   (2007-04-19 15:52:00) [10]


> Клиент


Чейклиент какогосервера ?

В 3-хзвенке, как правило, фигурируют 2 клиента: "тонкий" клиент сервера приложений, и сам сервер приложений как клиент некоей СУБД ..


clickmaker   (2007-04-19 15:41:00) [11]


> Клиент (их число пока не ограничивается) вызывает функции
> "Старт_Транзакции" и "Завершение_транзакции".

не клиентское это дело
транзакциями должен управлять сервер. В идеале - именно SQL-сервер


Наверх

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