Данная статья о работе в режиме Оффлайн с БД. Идея в том, чтобы большую часть времени работать без соединения с базой данных. А с базой соединяться только тогда, когда нужно. Ведь и правда, есть такие задачи, для которых режим оффлайн был бы идеальным – нестабильная сеть или ограниченные вычислительные ресурсы. Основа данной статьи – официальная документация
Включение Оффлайн режима
Здесь все достаточно просто. Для того, чтобы включить режим оффлайн, необходимо
-Вызвать TFDCustomConnection.Offline метод
-Присвоить параметру AAction метода FDCustomConnection.OnRecovery значение faOfflineAbort
По поводу последнего параметра в справке написано следующее
То есть, это выглядело бы таким образом
1 2 3 4 5 6 |
procedure TForm1.FDConnection1Recover(ASender, AInitiator: TObject; AException: Exception; var AAction: TFDPhysConnectionRecoverAction); begin AAction:=faOfflineAbort; showmessage('Connection Lost, now is OfflineMode'); end; |
Интересный момент!
Все активные датасеты, перед уходом в оффлайн “фетчатся” (получаются) в зависимости от настроек свойства FetchOptions.AutoFetchAll, по умолчанию там стоит afAll. То есть, говоря по русски – все множества загружаются полностью до ухода в оффлайн. На мой взгляд, это хорошо для небольших множеств в 100,200 – 1000 записей, а вот если там под 1000 000 записей, то придется выкручиваться и ставить другой режим, например afDisabled.
Выключение Оффлайн режима
-Явный вызов TFDCustomConnection.Online
-Неявная активация, когда приложению нужно “пообщаться” с БД, например отправить обновления, команду на выполнение и так далее
При этом ResourceOptions.AutoConnect свойство должно быть поставлено в True.
Практика
Тестируем включение / выключение оффлайн режима
Для начала напишем приложение, которое двумя способами уходит в оффлайн и возвращается обратно. Используем опыт прошлых постов и кнопку bConnect обработаем следующим образом
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure TForm1.bConnectClick(Sender: TObject); begin Self.AddConnectionDef(Self); FDConnection1.ConnectionDefName:='MySQL_Persistent_def'; FDConnection1.Connected := True; if FDConnection1.Connected then showmessage('Connected') else showmessage('could not connect'); FDConnection1.Offline; if FDConnection1.Offlined then showmessage('Offline'); end; |
В результате получим такое сообщение
Имитируем обрыв соединения
Теперь обработаем событие OnRecover таким образом
1 2 3 4 5 6 |
procedure TForm1.FDConnection1Recover(ASender, AInitiator: TObject; AException: Exception; var AAction: TFDPhysConnectionRecoverAction); begin AAction:=faOfflineAbort; showmessage('Connection Lost, now is OfflineMode'); end; |
А сам обрыв соединения сделаем, отключив демона MySQL таким образом из cmd (под администратором)
1 |
net stop MySQL |
В windows 8 можно сделать таким образом – нажать Ctrl X, далее выбрать “Командная строка (администратор)”, далее согласиться с диалоговым окном, набрать net stop MySQL. Можно также создать bat файл и написать там ту же самую инструкцию net stop MySQL, но запустить его нужно будет от имени администратора.
В этом случае от нашего приложения получим такой ответ
Работа с данными в оффлайн режиме
Теперь посмотрим как можно работать с данными в режиме оффлайн. Немного расширим нашу программу, таким образом.
Обработку кнопок сделаем следующую
Offline_Online
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
procedure TForm1.Offline_OnlineClick(Sender: TObject); begin if FDConnection1.Offlined then begin FDConnection1.Online; Form1.Caption:='Online'; end else begin FDConnection1.Offline; Form1.Caption:='Offline'; end; end; |
Open
1 2 3 4 5 6 7 |
procedure TForm1.OpenClick(Sender: TObject); begin FDQuery1.Open('select*from employee'); if FDConnection1.Offlined then Form1.Caption:='Offline' else Form1.Caption:='Online'; end; |
Insert
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
procedure TForm1.InsertClick(Sender: TObject); begin FDQuery1.SQL.Text:='insert into employee '+ '(Name,Family,Age,Salary,Department_key) '+ 'values (''SomeName'',''SomeFamily'',32,300000,1);'; FDQuery1.ExecSQL; FDQuery1.Open('select*from employee'); if FDConnection1.Offlined then Form1.Caption:='Offline' else Form1.Caption:='Online'; end; |
Delete
1 2 3 4 5 6 7 8 |
procedure TForm1.DeleteClick(Sender: TObject); begin FDQuery1.Delete; FDQuery1.Open('select*from employee'); if FDConnection1.Offlined then Form1.Caption:='Offline' else Form1.Caption:='Online'; end; |
ApplyUpdates
Здесь, для корректной работы нужно включить режим CachedUpdates
1 2 3 4 5 6 |
procedure TForm1.ApplyUpdatesClick(Sender: TObject); begin FDQuery1.ApplyUpdates(-1); if FDConnection1.Offlined then Form1.Caption:='Offline' else Form1.Caption:='Online'; end; |
Режим FDQuery.CachedUpdates – режим кэширования обновлений
Очень интересный режим – по сути для тех задач, для которых нам не нужен постоянный многопользовательский доступ к одним и тем же данным мы можем кэшировать наши обновления и отправлять их одной партией. На мой взгляд, здесь нужно исходить из задачи, которая решается программистом.
Аналогом ему в DBExpress являлись компоненты SimpleDataSet и ClientDataSet.
Если мы работаем в режиме CachedUpdates, то код для Insert,Delete и др. методов нужно немного поменять и вставить туда ApplyUpdates(-1), примерно таким образом….
1 2 3 4 5 6 7 8 9 |
procedure TForm1.DeleteClick(Sender: TObject); begin FDQuery1.Delete; FDQuery1.ApplyUpdates(-1); FDQuery1.Open('select*from employee'); if FDConnection1.Offlined then Form1.Caption:='Offline' else Form1.Caption:='Online'; end; |
То есть обновления должны происходить до получения данных, до метода Open.
В принципе, программа показала, что если войти в Offline режим, а потом отправить команду insert, delete или open, то подключение к базе возобновляется автоматически. Режим кэширования обновлений может сильно снизить нагрузку на сеть для тех задач, где это возможно – там где не нужен постоянный много пользовательский доступ к базе данных, например доступ одного человека – администратора.