Суббота
16.12.2017
21:29


Форма входа

Приветствую Вас Гость | RSS
Borland Delphi 7
Главная Регистрация Вход
Главная » 2009 » Март » 21 » Использование баз данных Paradox в локальной сети
Использование баз данных Paradox в локальной сети
20:26
Хотелось бы поделиться опытом использования баз данных Paradox в локальной сети. По большому счету, принципы распределенного и локального доступа к таблицам Paradox ничем не отличаются. Исключения составляют некоторые правила и рекомендации, которые изложены ниже...

В последнее время в сторону BDE раздается много замечаний и нареканий по поводу ограниченности и ненадежности при организации сетевого доступа к файлам БД.
Существует множество решений и хитростей, призваных облегчить жизнь разработчику, работающему с BDE. Как показывает опыт, такие эксперименты чаще всего приводят к частичной и полной потере данных в файловых таблицах... Отсюда правило первое : если вы хотите использовать Paradox в сети, установите BDE в полном объеме на каждой клиентской машине, включая ту, где находятся файлы базы данных. Обязательны следующие установки в конфигурации на каждой машине :
Это предотвратит Sharing Violation :
BDE->Configuration->System->Init : LOCAL SHARE = TRUE
BDE->{Самое важное}
Это предотвратит неразбериху в местоположении данных.

BDE не работает с базами данных напрямую, как например \\head\C\Database.
Диск с данными необходимо подключить как сетевой. Еще лучше, если буквы сетевого диска будут одинаковыми на всех машинах...
BDE->Configuration->
Drivers->
Native->
Paradox : NETDIR = F:\Databse,
BDE->где F = \\head\c\
Возникает резонный вопрос : а что если баз данных несколько?
Тогда в качестве NETDIR необходимо указать корневой каталог, в нашем случае F.
Если вы работаете с файловыми базами данных, то вам необходимо воспринимать BDE как некоторый сервис, как скажем, interbase. Сравнение конечно не из лучших, однако нормально работающий BDE - залог сохранности и надежности ваших данных.

К вопросу о Refresh.
Если вы работаете локально, то никаких проблем с обновлением набора данных у вас не возникает. При изменении данных, вы сразу видите результат на экране. В сети ситуация несколько иная : пользователи на других компьютерах не видят тех изменений, которые происходят без их участия. Конечно, ничто не мешает нам через определенные интервалы времени обновлять элементы управления с помощью Refresh, однако не очень приятно наблюдать за тем, как ваша программа превращается в новогоднюю елку, постоянно мерцая элементами управления. Проблема решается с помощью BDE Callback Functions :
// Объявления...  
TForm1 = class(TForm)
// ...
public
function TableChangeCallBack(CBInfo: Pointer): CBRType;
procedure UpdateTableData(var Msg: TMessage);
message WM_UPDATETABLE;
procedure TablesAfterOpen(DataSet: TDataSet);
end;

// Реализация...
function TForm1.TableChangeCallBack(CBInfo: Pointer): CBRType;
begin
PostMessage(Handle, WM_UPDATETABLE, 0, 0);
end;

procedure TForm1.UpdateTableData(var Msg: TMessage);
Var
Index : Integer;
begin
For Index := 0 To DBDataModule.ComponentCount - 1 Do
// DBDataModule - это Data module, в котором находятся все
// TTable нашего проекта...
If DBDataModule.Components[Index] Is TTable Then
If TTable(DBDataModule.Components[Index]).State = dsBrowse
then TTable(DBDataModule.Components[Index]).Refresh;
end;

procedure TForm1.TablesAfterOpen(DataSet: TDataSet);
begin
TBDECallback.Create(Self, TTable(DataSet).Handle,
cbTableChanged, nil, 0, TableChangeCallBack, True);
end;
// На событие OnCreate в Data Module
// подключаем наши функции к TTable...
procedure TDBDataModule.DBDataModuleCreate(Sender: TObject);
Var
Index : Integer;
begin
For Index := 0 To ComponentCount - 1 Do
If Components[Index] Is TTable Then
TTable(Components[Index]).AfterOpen := Form1.TablesAfterOpen;
end;
Но и это еще не все... Теперь нам нужен TTimer...
procedure TForm1.FrashmanTimer(Sender: TObject);
Var
Index : Integer;
begin
Try
For Index := 0 To DBDataModule.ComponentCount - 1 Do
If DBDataModule.Components[Index] Is TTable Then
If (TTable(DBDataModule.Components[Index]).Active)
And
(TTable(DBDataModule.Components[Index]).State = dsBrowse)
Then
DBIForceReRead(TTable(DBDataModule.Components[Index]).Handle);
Except End;
end;

Сохранность данных в сети.
Для того чтобы быть уверенным в сохранности данных, необходимо на событие AfterPost Компонета TTable назначить следующее :
dbiSaveChanges(TTable(DataSet).Handle);

Блокировки.
Существует два подхода к разделенному изменению данных : оптимистический и писсимистический. В первом случае речь идет о клиент-сервере и транзакциях. Иначе говоря, сколько угодно пользователей могут одновременно изменять одни и те же данные.
В нашем случае такой возможности просто не существует. Необходимо самим предусмотреть ситуацию, когда пользователи, например, попытаются одновременно редактировать одну и ту же запись. Ничего страшного, кроме сообщения "record locked by another user", не произойдет.
Однако желательно самим обработать данную ситуацию. Вот пример функции, которая проверяет, заблокирована запись или нет :
Function IsRecordLocked(Table: TTable) : Boolean;
Var
Locked: BOOL;
hCur: hDBICur;
rslt: DBIResult;
begin
Table.UpdateCursorPos;
Check (DbiIsRecordLocked (Table.Handle, Locked));
Result := Locked;
if (Result = False) then
begin
Check(DbiCloneCursor (Table.Handle, False, False, hCur));
try
rslt := DbiGetRecord (hCur, dbiWRITELOCK, nil, nil);
if rslt <> DBIERR_NONE then
begin
if HiByte (rslt) = ERRCAT_LOCKCONFLICT then Result := True
else Check (rslt);
end
else
Check (DbiRelRecordLock (hCur, False));
finally
Check (DbiCloseCursor (hCur));
end;
end;
end;


Обсуждения на форуме

Категория: Статьи участников клуба | Просмотров: 1148 | Добавил: delphi | Рейтинг: 0.0/0 |
Всего комментариев: 0
Имя *:
Email *:
Код *:
Меню сайта

Разделы новостей
Программные обеспечения [6]
Учебники и справочники Delphi [15]
Лабораторные работы [2]
Статьи участников клуба [36]
Советы и трюки [1]

Календарь новостей
«  Март 2009  »
ПнВтСрЧтПтСбВс
      1
2345678
9101112131415
16171819202122
23242526272829
3031

Поиск

Друзья сайта

Мини-чат

Наш опрос
Какой раздел нужно добавить на сайт и на форум?
Всего ответов: 56

Статистика

Copyright MyCorp © 2017