Використання моделі briefcase при розробці
додатків баз даних h2>
Використання коштів ADO. h2>
Михайло Голованов p>
Вимоги бізнесу щодо забезпечення роботи мобільних
користувачів
h2>
Впровадження інформаційних систем для автоматизації
діяльності бізнесу вимагає від розробників баз даних реалізації все нових
можливостей в розроблюваних ними додатках. Створення програмного
забезпечення, що дозволяє користувачам працювати лише в межах офісу, на
сьогоднішній день стає явно недостатньо. Співробітникам офісу потрібно
забезпечити доступ до інформаційних масивів фірми у відрядженні, з дому, з
офісу клієнта. При цьому користувачі хочуть не тільки переглядати дані, але й
мати можливість вносити до них зміни. Важливим вимогою з боку
адміністраторів інформаційних систем є простота установки і настройки
клієнтських додатків. p>
Підводячи підсумок вищесказаного, можна виділити основні
вимоги замовників до програмного забезпечення для мобільних клієнтів
інформаційної системи: p>
Можливість отримання даних, співробітниками поза
меж офісу фірми. p>
Можливість внесення мобільним клієнтом змін до
дані, які потім повинні бути синхронізовані з центральною БД. p>
Можливість роботи мобільного клієнта за відсутності
постійного каналу зв'язку з офісом. p>
Простота установки, настройки та експлуатації створених
додатків. p>
Технічні проблеми і варіанти реалізації
h2>
При реалізації вищезазначених вимог замовників
виникають наступні технічні проблеми: p>
Забезпечення зберігання отриманої користувачем
інформації в перервах між сеансами зв'язку з центральним офісом з можливістю
продовження роботи мобільного користувача. Іншими словами користувач не
повинен помічати відмінностей у роботі програми в режимах on-line та off-line. p>
Синхронізація зроблених користувачем змін з
центральною базою. Оскільки час між редагуванням запису мобільним
користувачем і внесенням її в центральну базу може становити дні, тижні і
навіть місяці застосування звичайного для моделі клієнт-сервер механізму блокувань
записів не має сенсу. При цьому кілька мобільних користувачів можуть
одночасно редагувати кожен свою копію даних з сервера, тоді при
спробі синхронізації даних неминуче виникнення конфліктів змін
внесених в одну і ту ж запис різними користувачами. Дані конфлікти --
це конфлікти синхронізації. Забезпечення засобів вирішення конфліктів
синхронізації-це одна з головних вимог до технічної реалізації такого
ПЗ. p>
Далі ми коротко розглянемо найбільш часто
застосовуються варіанти рішення задачі доступу мобільних користувачів до
центральній базі даних. p>
Використання Internet і Web
h2>
Web спочатку проектувалася як територіально
розподілена мережа, що дозволяє здійснювати доступ до різних інформаційних
ресурсів у режимі on-line. Основним недоліком даного підходу є
необхідність бути постійно підключеним до мережі. Цей недолік практично
не дозволяє застосовувати даний підхід для роботи мобільних користувачів. p>
Реплікація баз даних
h2>
Реплікація - це процес синхронізації даних між
декількома серверами БД. Описаний метод роботи архітектура
системи виглядає наступним чином: p>
p>
Малюнок 1 p>
Більшість сучасних серверів БД мають вбудовані
засоби для підтримки реплікації, що дозволяють обмінюватися даними між
декількома серверами. Клієнтський додаток при цьому не вимагає особливих
модифікацій. Головним недоліком такого методу є необхідність установки
та обслуговування сервера БД на машині клієнта. p>
Модель роботи briefcase
p>
Briefcase модель має на увазі роботу клієнта з базою
даних без підтримки постійного з'єднання. Клієнт підключається до БД,
завантажує необхідні дані, передає зроблені ним зміни, і тут же
вимикається. У Delphi дана модель може бути реалізована з використанням
можливостей ADO або MIDAS. p>
При створенні програми, що реалізує модель briefcase
можна виділити кілька підзадач: p>
Отримання даних з центрального сервера; p>
Збереження даних в локальний кеш; p>
Завантаження даних з локального кеша; p>
Синхронізація даних з центральним сервером і
обробка помилок синхронізації. p>
Для наших прикладів як сервер БД я використовував
MS SQL сервер. На ньому була створена база даних ParamsHolder, що містить усього
одну таблицю Params з наступними полями: p>
Поле p>
Тип p>
Опис p>
ParamID p>
Int p>
Первинний ключ, identity p>
ParamName p>
Varchar (50) not null p>
Назва зберігається параметра p>
ParamValue p>
Varchar (50) p>
Значення параметра p>
Каркас головної форми програми наведено на малюнку. Я
не буду детально описувати каркас, при необхідності Ви можете звернутися до
комплекту прикладів.
p>
p>
Малюнок 2 p>
Відзначимо лише, що компонент підключення до сервера
названий ParamConns, а компонент доступу до даних ParamsCS. Зосередимося на
реалізації перерахованих вище підзадач створення додатку briefcase. Всі
перераховані підзадачі реалізовані за допомогою Action-нов. p>
Реалізація моделі briefcase засобами ADO
p>
Оскільки компоненти доступу до даних через ADO мають
можливість зберігати і завантажувати дані у/з файл, вони придатні для розробки
додатків briefcase. p>
Отримання даних з центрального сервера
p>
Код для реалізації отримання даних з центрального
сервера, для подальшого обговорення рядка коду пронумеровані: p>
procedure
TForm1.act_RemoteConnectExecute (Sender: TObject); p>
begin p>
1 try p>
2 try p>
3
with ParamsCS do p>
4
begin p>
5
Close; p>
6
CommandType: = cmdText; p>
7
CommandText: = sqlText; p>
8
Connection: = ParamsConn; p>
9
Open; p>
10 end; p>
11 act_SaveLocal.Execute; p>
12 except p>
13 on E: Exception do p>
14 MessageDlg (Format (msgServerConnectError,
[E. Message]), mtError, [mbOk], 0); p>
15 end; p>
16
finally p>
17 ParamsConn.Connected: = false; p>
18
act_ConnectLocal.Execute; p>
19 end; p>
Завдання даного коду підключитися до центрального
серверу, отримати дані і зберегти їх в локальний кеш для подальшого
використання. p>
Блок try ... finally (рядки 1, 12-15) дозволяє нам поза
залежно від успішності підключення до сервера відключитися від нього і
відобразити користувачеві дані з локального кеша. Код для безпосередньо
підключення до сервера та завантаження даних міститься в рядках 2-10. Блок try
except забезпечує обробку помилок отримання даних з сервера. При
виникненні помилки користувачу відображається повідомлення про неможливість
підключення. Код, безпосередньо реалізує отримання даних, це рядки
5-9. У цих рядках ми налаштовуємо компонент класу TADODataset (ParamsCS) на
роботу з сервером і відкриваємо. Ви запитаєте: навіщо це робити кожного разу. Робити
це потрібно тому, що при відкритті локального кешу (за допомогою методу
TADODataset.LoadFromFile) датасет сам перебудовує свої властивості CommandType і
CommandText. Метод LoadFromFile викликається всередині акції act_ConnectLocal. Після
отримання з сервера ми зберігаємо вибірку на локальний кеш, викликавши відповідний
Action (рядок 11). P>
Збереження даних в локальний кеш p>
Для забезпечення можливості роботи з даними без
постійного підключення до сервера (і постійно завантаженої програми)
необхідно зберігати отримані дані і зроблені користувачем зміни.
Компоненти ADO (Спадкоємці TCustomADODataset) мають можливість зберігати
вибірку даних у файл, використовуючи метод SaveToFile. Метод має два параметри.
Перший - ім'я файлу, другий формат збереження даних. Підтримуються два формати
збереження даних: p>
XML p>
ADTG (Advanced Data Tablegram) p>
За замовчуванням збереження відбувається у форматі ADTG,
хоча особисто я вважаю за краще збереження у форматі XML, тому що він більш зручний для
сприйняття даних людиною. p>
ПРИМІТКА p>
Якщо ім'я файлу має розширення XML,
дані зберігаються у форматі XML, ігноруючи другий параметр методу SaveFile. p>
Код збереження даних в локальний кеш складається з лише
виклику методу ParamsCS.SaveFile. p>
Завантаження даних з локального кеша
p>
Для завантаження даних з файлу спадкоємці
TCustomADODataSet мають метод LoadFromFile. Перед завантаженням з файлу властивість
Connection у ParamsCS необхідно встановити в nil, тому що під час завантаження
здійснюється спроба підключитися до сервера БД. Код представлений нижче: p>
procedure
TForm1.act_ConnectLocalExecute (Sender: TObject); p>
begin p>
ParamsCS.Connection: = nil; p>
ParamsCS.LoadFromFile (ExtractFilePath (Application.ExeName) + ParamFile); p>
end; p>
ПРИМІТКА p>
Виклик LoadFromFile автоматично змінює
тип команди датасета (св-во CommandType) на cmdFile і в властивість CommandText
зберігає ім'я файлу, звідки була проведена завантаження. p>
Синхронізація даних з сервером
p>
Синхронізація включає в себе передачу зроблених
користувачем змін та отримання інформації з сервера оновлених (оновлення від всіх
користувачів) даних. Отримання даних з сервера ми вже розглянули і тут
зупинимося на проблемі передачі змін в центральну базу. Завдання передачі
змін може бути розділена на дві непосредсвтенно передачу та обробку
помилок синхронізації. p>
Передача змін здійснюється викликом методу
UpdateBatch. Як ми вже говорили, причиною помилок синхронізації є
одночасне редагування одного запису декількома користувачами. За
умовчанням запис на сервері відшукується ключового поля і поля, в яких
користувач зробив зміни. При цьому якщо інший користувач встиг зробити
в тих же полях цього запису зміни та внести їх до бази, запис не може бути
виявлена. Виникає помилка синхронізації. Алгоритм пошуку запису
контролюється властивістю Update Criteria об'єкту ADO RecordSet. Update Criteria
може приймати наступні значення: p>
AdCriteriaAllCols p>
Пошук за сукупністю всіх стовпців.
Найбільш «жорсткий» режим. P>
AdCriteriaKey p>
Пошук тільки по ключових полях.
Найбільш «м'який» режим. Конфлікт виникає лише при видаленні запису з бази. P>
AdCriteriaTimeStamp p>
Якщо в таблиці є поле типу TimeStamp
для синхронізації буде використано воно p>
AdCriteriaUpdCols p>
Пошук за сукупністю ключових полів і
полів, що містять зміни даних p>
При виявленні помилок синхронізації генерується
виняткова ситуація класу EOleError c повідомленням про неможливість зберегти
зміни. Обробка помилок синхронізації підтримується в ADO, починаючи з
версії 2.7. При цьому алгоритм вирішення конфліктів, наведений в MSDN,
Наступне: p>
Властивість Filter об'єкта Recordset ADO встановити
рівним adFilterConflictingRecords. При цьому будуть відображені тільки конфліктні
запису. p>
Викликати метод Resync того ж об'єкта з параметром
AffectRecords рівним adAffectGroup, параметр ResyncValues рівним
adResyncUnderlyingValues, при цьому будуть отримані оновлені дані про
стані конфліктних записів з сервера. Актуальні значення полів записів
рекордсета зберігаються у властивості UnderlyingValue об'єкта Field, початкові в
OriginalValue, а змінені користувачем в Value. P>
відобразивши користувачеві набір конфліктних записів і
значення їх полів ми даємо йому можливість відредагувати конфліктні запису і
усунути конфлікти. p>
Записати в БД зміни користувача можна викликавши
UpdateBatch з параметром adAffectGroup. P>
Обробку помилок я виніс в окремий модуль
ADOReconcileError. У ньому визначено процедуру HandleADOReconcileError,
що відповідає за підтримку обробки помилок синхронізації. Сам же код
синхронізації виглядає так: p>
try p>
ParamsConn.Connected: = true; p>
ParamsCS.Connection: = ParamsConn; p>
ParamsCS.UpdateBatch; p>
except p>
on E: EOleException do begin p>
HandleADOReconcileError (ParamsCS); p>
end else raise; p>
end; p>
act_RemoteConnect.Execute; p>
Скасування внесених змін
p>
Ще однією особливістю використання ADO є
можливість користувачеві скасування зроблених ним змін. Дана можливість
реалізується методом CancelBatch. Коли Ви робите c параметром arAll (параметр по
замовчуванням) скасовуються всі зроблені зміни. Коли Ви робите з параметром
arCurrent будуть скасовані зміни, внесені в поточну запис датасета. p>
У наступній частині статті буде розглянута реалізації
моделі briefcase за допомогою засобів MIDAS. p>
Список літератури h2>
Для підготовки даної роботи були використані
матеріали з сайту http://www.rsdn.ru/
p>