Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.03;
Скачать: CL | DM;

Вниз

транзакции в распределенной БД   Найти похожие ветки 

 
wardoc ©   (2006-06-25 02:27) [0]

Доброго времени суток уважаемые.

У меня такая проблема: делаю я клиент-серверную БД, использую в качестве сервера БД Interbase, сама база данных распределена в локальной сети с использованием DCOM. Разумеется хочется, чтобы БД была с многопользовательским доступом. Поэтому использую ессно транзакции. При добавлении/изменении записей клиентским приложением все вроде бы обновляется в БД благополучно, но если тут же делаю попытку добавления/изменения записи этой же таблицы из второго экземпляра клиентского приложения, то возникает такое вот исключение: "Cannot perform this operation on a closed database", или что-то в этом роде. Хотя компоненты связи с БД открыты. Что я делаю не так?


 
Ломброзо ©   (2006-06-25 12:16) [1]

неправильная архитектура.
Сервер приложений должен управлять распределением нагрузки на СУБД, для чего обычно реализуется механизм, обеспечивающий кэширование и повторное использование соединений  к БД (сonnection pooling). В случае применения компонентов ADO этот механизм встроен в библиотеки OLE DB, поэтому нет смысла открывать и держать соединение открытым в течение всего времени жизни процесса. Другими словами, правильный код для доступа к данным должен выглядеть примерно так:

procedure GetData();
var
 cnn: TADOConnection;
 rs  : TADORecordset;
begin
 try
    cnn := TADOConnection.Create();
    cnn.COnnectionString := "...";
    cnn.Open();
    rs := cnn.Execute("select * from ...");
 finally
    if (cnn <> nil) then
    begin
      cnn.CLose();
      cnn.Free();
      cnn := nil;
    end;
 end;
end;

То есть основной принцип такой: создать соединение - открыть - сделать запрос - сразу же закрыть.

В вашем случае, насколько я понял, ошибка состоит в том, что компонент-соединение у вас лежит на форме или в DataModule в единственном экземпляре. Представьте, что к вашему приложению одновременно обратились два клиента. Первый открыл соединение, и выбирает данные. Второй при попытке открыть соединение получит исключение с сообщением о том, что соединение уже открыто и используется. Для устранения этой ткзать коллизии нужно:
- Писать код так, как указано в примере выше;
- Использовать примитивы синхронизации (например, критические секциии) для обеспечения гарантии того, что два процесса или потока не смогут одновременно обращаться к общей переменной.

Ну и ещё, наверное, я бы на вашем месте отказался от DCOM и использовал бы COM+.


 
ВЫЛфдгпшт   (2006-06-26 14:22) [2]

В Интербейзе есть такое понятие как Двухфазный коммит. Изменение данных на разных серверах в контексте одной общей транзакции.
Возможно использование этого механизма решит вашу проблему


 
DSKalugin ©   (2006-06-26 14:27) [3]

ВЫЛфдгпшт=DSKalugin
не той раскладкой свой ник написал :-)

Автоматический коннект, транзакцию и отсоединение реализовано в библиотеке dbExpress насколько я правильно понял
http://ibase.ru/devinfo/dbexpress.htm


 
wardoc ©   (2006-06-27 15:26) [4]

2Ломброзо:
Я не использую ADO, но все равно спасибо за совет закрывать соединение после обмена данными. Что касается того, что компонент-провайдер лежит в модуле данных в единственном экземпляре - да это так, но ведь настройки модуля данных таковы, что на каждого подключенного клиента в память загружается отдельный экземпляр модуля данных. Разве это не должно обеспечивать многопользовательский доступ, даже если компоненты открыты? COM+ обязательно попробую.

2DSKalugin:
За ссылку на инфу по dbExpress большое спасибо. Двухфазный коммит - изменение данных на разных серверах? Это клиент должен быть подключен к разным серверам одновременно что-ли?



Страницы: 1 вся ветка

Текущий архив: 2006.09.03;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.048 c
15-1155113314
DelphiLexx
2006-08-09 12:48
2006.09.03
Нужен русский Help к RxLib


15-1155024024
__DATA__
2006-08-08 12:00
2006.09.03
Заменить один класс компонентов на другой


15-1155312600
IMHO
2006-08-11 20:10
2006.09.03
Отбор к Евро-2008


2-1155237353
ArtemESC
2006-08-10 23:15
2006.09.03
Как убрать Beep при нажатии Enter при вводе в TEdit?


15-1154669236
Ega23
2006-08-04 09:27
2006.09.03
С Днём рождения! 4 июля. Нет. 4 августа.