4. Snyder. Encapsulation and Inheritance in Object-Oriented Programming Languages. In Conference proceedings on Object-oriented programming systems, languages and applications, 1986.
5. Taivalsaari. On the Notion of Inheritance. In ACM Computing Surveys, Vol. 28, No. 3, September 1996.
6. P. Wegner. Concepts and Paradigms of Object-Oriented Programming. In ACM SIGPLAN OOPS Messenger, Vol. 1, Issue 1, August 1990.
УДК 004.652.4:004.045
ОРГАНИЗАЦИЯ РЕПЛИКАЦИИ ДАННЫХ ПРИЛОЖЕНИЯ С ORM-СЛОЕМ НА
ОБЪЕКТНОМ УРОВНЕ
Ипполитов Вадим Дмитриевич, студент, Факультет информационных технологий, Новосибирский государственный университет, Россия, Новосибирск, vadipp@gmail.com
Кременная Ольга Александровна, студентка, Факультет информационных технологий, Новосибирский государственный университет, Россия, Новосибирск, kremennaya.olga@gmail.com Тищенко Николай Анатольевич, студент, Факультет информационных технологий, Новосибирский государственный университет, Россия, Новосибирск, niktischenko@gmail.com Баженов Николай Алексеевич, студент, Механико-математический факультет, Новосибирский государственный университет, Россия, Новосибирск, nickbazh@yandex.ru Вельдяксов Василий Николаевич, студент, Механико-математический факультет, Новосибирский государственный университет, Россия, Новосибирск, vasvel@yandex.ru
Задача репликации данных состоит в поддержании нескольких хранилищ данных в согласованном состоянии. Репликация может применяться для обеспечения отказоустойчивости, повышения производительности и локализации трафика [1].
Рассмотрим бизнес-приложение, использующее слой объектно-реляционного отображения (ORM) [2-3] для хранения своих данных. Пусть на нескольких компьютерах (узлах) установлены копии этого приложения, каждая из которых работает с собственной базой данных. Если целостность всех данных одной копии приложения сводится к целостности отдельных объектов и прямых связей между ними, то возможна репликация данных между узлами на уровне объектов. Для этого необходимо отслеживать, какие объекты изменяет бизнес-приложение, и при репликации распространять эти изменения на другие узлы. Все изменения в базу данных приложение вносит через ORM-слой, что позволяет отследить их прозрачно для приложения, внедрившись в этот слой.
Целью проекта «Чилим»7 является разработка механизма репликации данных на объектном уровне и реализация программной системы, основанной на этом механизме. Наиболее важные требования к системе:
• минимальность необходимых изменений кода бизнес-приложения,
• устойчивость к разрывам сетевых соединений,
• экономия сетевого трафика,
• независимость от СУБД.
На данный момент реализован функциональный прототип системы репликации. В качестве бизнес-приложения выступает система управления контентом XWiki [4] -приложение на языке Java, использующее библиотеку Hibernate [5] для доступа к РСУБД на объектном уровне.
Прототип системы состоит из 4-х основных модулей:
1. модуль логики репликации,
2. протокол сетевого взаимодействия,
7
Проект студенческой учебно-исследовательской
http ://parallels.nsu.ru/wiki/ReplicationProiect/
лаборатории НГУ-Parallels,
96
3. модуль работы с ORM-слоем,
4. интерфейс администрирования.
Код Hibernate был незначительно изменён, чтобы обеспечить подключение специального обработчика событий к каждой сессии работы приложения с базой данных. Модуль работы с ORM-слоем с помощью этого обработчика отслеживает три вида событий:
1. сохранение нового объекта (persist),
2. обновление содержимого ранее существовавшего объекта (update),
3. удаление объекта из базы данных (delete).
Сведения о модификациях бизнес-объектов, собранные репликатором, сохраняются в отдельной таблице Entities базы данных. Для каждого объекта хранятся:
1. глобальный идентификатор объекта (globalId),
2. первичный ключ объекта в базе данных текущего узла (hibernateKey),
3. дата последней модификации объекта приложением (modDate),
4. дата сохранения объекта в базе данных (saveDate).
Глобальный идентификатор присваивается каждому бизнес-объекту в момент первого сохранения приложением в базу данных и никогда не изменяется. С помощью globalId задаётся отношение эквивалентности на бизнес-объектах, иначе говоря, объекты с одинаковым globalId при репликации считаются версиями одного и того же бизнес-объекта. Глобальный идентификатор состоит из двух частей:
1. имя класса, к которому относится данный объект (entityName),
2. уникальный среди всех объектов этого класса в данной сети идентификатор (uniqueId).
Уникальный идентификатор вычисляется двумя способами, в зависимости от типа первичного ключа сущности [6]. Если первичный ключ присваивается базой данных автоматически (суррогатный ключ), то генерируется случайный GUID [7], который и становится uniqueId. Если же первичный ключ присваивается бизнес-приложением (естественный ключ), то в качестве uniqueId используется результат применения сжимающей взаимнооднозначной функции [8] к первичному ключу. Во втором случае считается, что два бизнес-объекта одного класса, которым на разных узлах приложение присвоило одинаковые ключи, являются по сути одним и тем же объектом, что наилучшим образом отражает идею естественного ключа. Сжатие позволяет уменьшить длину поля uniqueId во втором случае.
Дата сохранения объекта в базе данных (saveDate) позволяет отличать объекты, сохранённые в процессе репликации, от объектов, сохранённых локальной копией бизнесприложения. В первом случае дата сохранения больше даты модификации, во втором они равны.
Кроме таблицы Entities, каждый узел сети имеет таблицу Nodes, в которой хранятся даты последней репликации с теми узлами, с которыми она когда-либо производилась. Вышеупомянутой информации достаточно, чтобы производить репликацию методом распространения слухов [9].
Прототип системы поддерживает сессии репликации с участием только двух узлов одновременно. Один из узлов является активным (Local), второй - пассивным (Foreign). Узел Local инициирует все действия в текущей сессии, в том числе открывает сетевые соединения. В начале сессии Local строит список идентификаторов объектов, изменённых локально с момента последней репликации с узлом Foreign, сравнивая даты последних изменений объектов своей базы данных с датой последней репликации с Foreign. Назовём этот список LocalChanges. Затем он запрашивает у узла Foreign «симметричный» список ForeignChanges. Списки изменений содержат globalId и modDate. Получив ForeignChanges, узел Local сравнивает списки изменений и составляет три новых списка идентификаторов объектов:
1. ToPull - изменённые на узле Foreign, но не изменённые на Local,
2. ToPush - изменённые на узле Local, но не изменённые на Foreign,
3. Conflicts - изменённые на обоих узлах.
97
Если список конфликтов не пуст, то вызывается обработчик конфликтных изменений. Он решает, какая из двух версий объекта будет оставлена, а какая - удалена, основываясь на датах их модификации и, если нужно, содержимом объектов. Если разработчиками бизнесприложения не предоставлен специфический обработчик, то используется стандартный, который всегда решает конфликты в пользу последней версии объекта.
После разрешения конфликтов происходит проталкивание объектов из списка ToPush на узел Foreign и вытягивание с него объектов из списка ToPull [10-11]. Передача объектов происходит пачками настраиваемого размера, что позволяет с одной стороны, уменьшить накладные расходы на установление сетевых соединений, а с другой, обеспечить достаточную устойчивость к их неожиданным обрывам. Ошибки при передаче одной пачки не останавливают процесс репликации в целом. На каждую полученную пачку объектов узел отвечает списком идентификаторов успешно сохранённых в своей базе данных объектов из этой пачки. Сохранение объекта может быть неудачным, например, в том случае, когда локальная модификация объекта произошла уже после составления списка изменений. Если объект не был успешно сохранён по той или иной причине, попытка будет повторена в следующем сеансе репликации.
Описанный механизм обеспечивает репликацию объектов, связи между которыми полностью отражены в их отображении на реляционную БД. Однако зачастую приложение построено так, что реализации бизнес-объектов не учитывают некоторые связи и ограничения, существующие в БД. И наоборот, существуют логические зависимости бизнесобъектов, влияющие на корректность работы приложения, но не отражённые в структуре базы данных. Такие ситуации были выявлены при анализе поведения XWiki. Например, два класса отображены на одну таблицу БД, причём у класса A есть обязательный атрибут, которого нет у класса B. Возникает неочевидная зависимость между этими классами: в БД необходимо сначала сохранять объект класса A, а потом B, если у них одинаковые ключи. В противном случае возникнет нарушение ограничения БД, поскольку у B отсутствует обязательный для этой таблицы атрибут.
Одно из решений заключается в исправлении структуры базы данных разработчиком приложения. Если же это невозможно, требуется задействовать дополнительные механизмы на этапе репликации. Разработчик бизнес-приложения должен предоставить файл описания зависимостей между объектами. В этом файле паре «класс объектов - загрузчик» сопоставляется модель отношения, определяющая порядок сохранения зависимого объекта. «Загрузчик» - это Java-класс, отыскивающий для зависимого объекта все объекты в базе данных, от которых он зависит. Загрузчики должен создать разработчик бизнес-приложения, поскольку именно он знает, каким образом объекты зависят друг от друга.
Файл описания зависимостей используется для поиска связей между объектами. В процессе построения списка изменений (*Changes) узлы отыскивают зависимости изменённых объектов друг от друга или от неизменённых объектов. Все найденные зависимости передаются вместе со списком изменений объектов. В процессе обмена изменёнными объектами (ToPull и ToPush) информация о связях используется при сохранении объекта в базу данных. В текущей версии прототипа системы данный механизм реализован лишь частично.
Основные преимущества выбранного подхода перед стандартными методами репликации при решении поставленной задачи:
1. Сеанс репликации не является транзакционным, поэтому обрыв связи не влечёт к удалению уже переданных объектов;
2. Разработчик бизнес-приложения может написать объектно-ориентированные обработчики сложных ситуаций (конфликтов или неявных зависимостей), в которых все данные доступны в виде бизнес-объектов.
Для целей администрирования сети узлов имеется веб-интерфейс. Он позволяет подключиться к указанному узлу, изменить его настройки, изменить расписание сеансов репликации, инициировать немедленную репликацию с другим узлом.
98
В ходе работы были выявлены требования к бизнес-приложению, при выполнении которых система репликации способна корректно функционировать. Эти требования носят характер промежуточных ограничений. Некоторые из них можно ослабить или убрать, введя новые механизмы в процесс репликации. Основные из них:
1. Все операции обновления базы данных происходят через ORM-слой, причём без использования прямых HQL запросов [12] типа “UPDATE ... SET ...” и “DELETE FROM ...”;
2. Любой бизнес-объект можно корректно загрузить штатными средствами Hibernate
[13];
3. На одну таблицу БД отображено не более одного бизнес-класса;
4. Все бизнес-классы допускают сериализацию и десериализацию с помощью какого-либо механизма, например, XStream [14].
Приведение XWiki в соответствие с этими требованиями позволило создать работающий прототип системы репликации.
Литература
1. Иртегов Д.В. Введение в сетевые технологии. — СПб.: БХВ-Петербург, 2004, стр.468
2. http://www.agiledata.org/essavs/mappingObiects.html (Mapping Objects to Relational Databases: O/R Mapping In Detail)
3. http://www.hibernate.org/about/orm.html (What is Object/Relational Mapping?)
4. http://www.xwiki.org/ (XWiki, an open-source wiki and content-oriented application platform)
5. http://www.hibernate.org/ (Hibernate, relational persistence for Java & .NET)
6. http://docs.iboss.org/hibernate/core/3.3/reference/en/html/mapping.html, Chapter 5.1.4.1. Generator (Hibernate documentation)
7. http://iava.sun.com/i2se/1.5.0/docs/api/iava/util/UUID.html#randomUUID() (Java 2 SE 5.0 documentation)
8. http://iava.sun.com/i2se/1.5.0/docs/api/iava/util/zip/Deflater.html (Java 2 SE 5.0 documentation)
9. Э. Таненбаум, М. ван Стеен. Распределенные системы. Принципы и парадигмы. — СПб.: Питер, 2003, стр.376
10. http://www.ibm.com/developerworks/lotus/library/ls-Domino Replication/index.html, PULL-PUSH (Notes from Support: Lotus Notes/Domino Replication)
11. Э. Таненбаум, М. ван Стеен. Распределенные системы. Принципы и парадигмы. — СПб.: Питер, 2003, стр.371
12. http://docs.iboss.org/hibernate/core/3.3/reference/en/html/quervhql.html (HQL: The
Hibernate Query Language)
13. http://docs.iboss.org/hibernate/stable/core/api/org/hibernate/Session.html#load(iava.lang.Stri ng,%20iava.io.Serializable) (Hibernate Core 3.5.0 API)
14. http://xstream.codehaus.org/ (XStream, a simple library to serialize otyects to XML and back)
УДК 004.422.81
КОРПОРАТИВНАЯ ИНФОРМАЦИОННАЯ СИСТЕМА ОБРАБОТКИ ЗАЯВОК НА
ОБСЛУЖИВАНИЕ
Бойко Алексей Павлович, студент, Томский Государственный Университет Систем Управления и Радиоэлектроники, Россия, Томск, flash-in-dark@vandex.ru
Уровень информатизации современного общества диктует условия необходимые для эффективного функционирования крупных компаний - сегодня трудно себе представить
99