ВходРегистрация
Евгений Игумнов
 

Добро пожаловать на сайт Евгения Игумнова (Evgeny.Igumnov.com)! На нем представлены три важных для меня направления: Бизнес планирование, Менеджмент и Информационные технологии. На страницах сайта можно найти примеры моих бизнес планов, а также статей по информационным технологиям и менеджменту. Кроме того опубликованы описания проектов в которых я участвовал. Мой моб. тел.: +79133869143 ICQ: 145593056 [Е-майл]

Добавить в избранное Отправить мне e-mail
Комментируемые записи
Практика по манипуляции с...
Комментарии: 27
Вирусный маркетинг - за и...
Комментарии: 8
Технология EJB
Комментарии: 5
Процесс разработки
Комментарии: 4
PHP
Комментарии: 3

Технология EJB

0.00 (0)

Методология построения корпоративных информационных систем на основе технологии EJB

Автор: Евгений Игумнов

Геокад Плюс (Новосибирск)

Опубликовано: 30.04.2001

Версия текста: 1.0

Введение

Думаю, расхваливать то, что будет написано мной сразу не стоит. Лучше сказать чего я постараюсь не написать. Если Вы хотите увидеть здесь учебник по которому можно научится основам EJB, то лучше Вам почитать книжки типа Corba за 14 дней. Если Вы ждете моих вздохов по перспективности и крутости технологии EJB, то Вам лучше почитать обзоры популярных компьютерных журналов. Если Вы ожидаете найти здесь обилие исходных примеров, да еще что бы они компилировались и работали, то Вам лучше почитать Manual от любого поставщика коммерческой или некоммерческой версии EJB сервера. В общем получается, что не совсем понятно, для кого я это все буду писать. Не знаю, как даже охарактеризовать моего потенциального читателя. Думаю, что я пишу это для себя самого. Но не для себя в данный момент, а для себя несколько месяцев назад. Дело в том, что не так давно я писал линейные программы без объектно-ориентированного подхода. Хотя прекрасно знал об ООП, но не использовал, так как считал это неудобным. Мне, к сожалению, пришлось решать несколько довольно сложных задач. И решал я их без ООП. Решал вполне успешно. Но вот когда пришло время модернизации разработанных систем... Я был просто подавлен. И тут меня судьба свела с человеком, который мне показал способы применения ООП: отображение объектов в БД, коллекции объектов и т.д. Имя этого человека Сергей Резинкин. Выражаю ему благодарность. Если бы не он... Другими словами мне нужен был толчок в верном направлении. Я стал интересоваться UML, потом CORBA, потом вышел на EJB и многое другое. Так вот я хочу Вам дать толчок в верном направлении. Я обозначу Вам путь. Многое здесь Вы, возможно, не воспримите по причине краткости изложения или отсутствия опыта, который бы позволил верно воспринять некоторые вещи. Надеюсь Вас задеть, что бы Вы сами дальше начали копать в этом направлении.

Архитектура технологии EJB

Чаще всего системы строятся следующим образом. Есть клиентское приложение, которое соединяется с сервером БД и посредством SQL запросов манипулирует данными, отображаемыми в клиентском GUI интерфейсе. Клиентская часть таких систем обычно очень сложная и на сервер баз данных возлагается, в основном задача, хранения и поддержки целостности данных. Иногда базы данных поддерживают хранимые процедуры, что позволяет снизить сетевой трафик между сервером и клиентом. Такая система изображена на рис. 1.

Рис.1

Такой подход имеет свои плюсы и минусы. В плюс идет относительно простая архитектура системы и относительно высокая скорость работы при небольшом количестве клиентских обращений к серверу. В минус идет то, что такую систему сложно модернизировать, так как изменение в БД влекут за собой изменения в клиентской части и наоборот. В случае нехватки ресурсов сервера, приходится либо наращивать его вычислительную мощность либо использовать распределенную БД, которая не всегда сможет решить возникшую проблему.

Существует другой подход построения информационных систем. Система разделяется на три уровня. Каждый уровень имеет свои обязанности и функциональные возможности. На первом уровне находится клиентское приложение, которое обычно "легкое" и занимается в основном презентационным слоем системы. Второй уровень отвечает за бизнес логику системы и взаимодействует с презентационным слоем, отвечая на его запросы. Вторым уровнем называют сервер приложения. На третьем уровне находится база данных, которая, как уже говорилось выше, отвечает за хранения данных и за их целостность. Такая система изображена на рис. 2.

Рис.2

Такой подход тоже имеет свои плюсы и минусы. В плюс идет разделение системы на уровни, позволяющее относительно легко модернизировать систему. Например, сегодня у Вас СУБД MySQL, а завтра Вы купили ORACLE и для этого Вам нужно поправить только второй уровень, а презентационный слой даже не заметит изменений. Или, например, Ваш второй уровень не очень оптимально работает и Вы решили его усовершенствовать, нет проблем: первый и третий уровень могут быть не затронуты. Еще одним преимуществом является возможность групповой работы над системой, в которой каждый из уровней разрабатывается независимо. Кто-то проектирует структуры баз данных, кто-то "рисует" презентационные слои, а кто-то пишет оптимальные алгоритмы. В добавок ко всему, компонентная технология EJB ориентирована на возможность распределения второго уровня, т.е. если Ваш сервер приложений не справляется с нагрузкой, то есть возможность без единого изменения кода сервера приложений, разнести его на несколько вычислительных машин. А компоненты, из которых состоит второй уровень, не будут чувствовать разницы между работой на одной вычислительной машине и на нескольких машинах. Минусом таких систем является их направленность на крупные корпоративные решения. Если Вы решаете задачу в которой небольшое количество обращений к серверу и малый бюджет на создание системы, то связавшись с EJB Вы будете стрелять из пушки по воробьям.

Многие спросят, а зачем вообще пользоваться EJB технологией? Можно и самому построить такую же систему, например, используя C++. Это конечно верно, но Вы будете изобретать велосипед и придете к такому же архитектурному решению, как в EJB, да и к тому же создание такой архитектуры довольно не тривиальная задача. Значительно дешевле и быстрей разобраться в правилах построения компонентов EJB архитектуры и строить по ее принципам свою систему на отлаженных технологиях. Да, чуть не забыл: EJB - Enterprise JavaBeans. Кстати на счет CORBA. Кто-то спросит, а почему бы не использовать CORBA архитектуру вместо EJB, которые работают не на очень скоростном языке JAVA? Отвечу довольно просто. В CORBA пока что не готова спецификация компонентов CORBA. Ну а тем более нет реализаций еще не готовой спецификации. Ну а кто вспомнит про DCOM, тех отсылаю к статьям, где проводится сравнительный анализ с CORBA, а после прочтения этих статей мой ответ сводится к тому, что DCOM пытается конкурировать с CORBA и проигрывает по нескольким критериям, да и к тому же не является компонентной технологией в "чистом" виде как EJB.

На самом деле JAVA продвигает 5 уровневую архитектуру на основе EJB, показанную на рис.3.

Рис.3

Пояснять ее я не буду, дабы не запутать читателя, а привел только для того, что бы часть читателей успокоилось на счет возможности построения много-уровневых систем на основе EJB.


Сервер приложений

Самое главное в EJB это сервер приложений. Без него у Вас ничего работать не будет. Клиентские приложения будут общаться с ним через RMI или CORBA. Обычно сервер приложений предоставляет Вашим EJB компонентам соответствующую среду. Например: хранит права доступа к Вашим компонентам (а точнее логины с паролями по доступу к серверу приложений), поддерживает RMI и CORBA взаимодействие с ними, предоставляет JNDI сервис (сервис именования EJB компонентов), координатор транзакций и контейнер, в котором будут храниться ваши EJB компоненты, сервис асинхронных сообщений JMS. Специалисты, которые это прочтут, будут возмущены грубыми ошибками. Дело в том, чтобы не грузить читателя, я довольно упростил и смешал некоторые вещи. Сервер Приложений изображен на рис. 4.

Рис.4

Как видно из рисунка, есть компьютер, на котором работает сервер и к нему есть доступ через RMI и CORBA. Внутри самого сервера приложений работают четыре службы и контейнер. Теперь немного подробнее о службах.

JNDI (Java Naming Directory Interface) - эта служба позволяет Вашим клиентскими приложениям находить на сервере приложений EJB компоненты по их имени. На самом деле Вы можете взять 10 компьютеров, объединить их в сеть, установить на них сервера приложений. Но сервис JNDI включить только на одном из них. И получится, что все компоненты EJB будут доступны на одном дереве имен, а работать на разных серверах приложений. Конечно, не зря я применяю термин дерево имен. Дело в том, что эта служба очень похожа на древовидную файловую структуру, где есть папки (контексты) и файлы (EJB компоненты). Я рассказываю это к тому, что на самом деле можно запустить на всех 10 компьютерах JNDI сервис, но настроить их так, что какой-то один из этих сервисов будет корневым, а все остальные будут подключены к нему и на общем дереве имен будут показаны как папочки (контексты).

Transaction Service - сервис транзакций. Этот сервис предоставляет похожие услуги транзакций, как в обычных реляционных базах данных. Только в данном случае нет SQL запросов и нет строчек базы данных вовлеченных в транзакцию. Вместо SQL запросов Вы вызываете методы изменяющие состояния компонентов и как только Вы начали транзакцию, то все объекты, с которыми Вы начнете работать будут в нее вовлечены. В конце Вы можете откатить изменения, сделанные Вами в объектах либо зафиксировать их.

Security Service - сервис безопасности. Так как сервер приложений предоставляет удаленный доступ к EJB компонентам, то вообще-то очень хорошо бы этот доступ ограничить. Для этого этот сервис и нужен.

JMS (Java Message Service) - сервис асинхронных сообщений. Есть возможность послать сообщение и не ждать подтверждение о получении или ответа. Например, когда Вы вызываете метод удаленного компонента, то Вам придется ждать, пока компонент отработает и вернет Вам значение. Хотя Вы конечно можете что-то делать в других нитях Вашего приложения. На самом деле JMS берет всю ответственность за доставку и хранения очередей сообщений, что значительно разгружает клиентские приложения. Поддерживаются механизмы: точка к точке, подписка, рассылка. Также, на стороне JMS подписчик может установить фильтр и получать только те сообщения, которые его интересуют.

Контейнер

Контейнер это контейнер. Он предоставляет среду, в которой могут функционировать Ваши компоненты EJB. Получается, у Вас есть контейнер, в который вы можете запихивать свои компоненты. Каковы функции контейнера? Их много:

  1. Разбор XML-описания компонента EJB (deployment descriptor) и поддержка конфигурации, описанной в этом XML-файле.
  2. Управление жизненным циклом компонента EJB, т.е. для предоставления услуг компонента прописанных в его интерфейсе и зарегистрированном на JNDI, необходимо создавать, уничтожать и кэшировать реализации (объекты), которые будут отвечать на запросы клиентов.
  3. Разбалансировка нагрузки между реализациями (объектами) обслуживающими компонент EJB и управление пулом таких объектов.
  4. Управление транзакциями в компонентах EJB. В случае с компонентами, которые работают с СУБД, управление транзакциями сильно связано с механизмом синхронизации состояния компонентов с состоянием СУБД.
  5. Управление безопасностью доступа к компонентам. Опционально эта функция может быть отключена и проверку прав доступа к методам Вашего компонента придется реализовывать своими руками в самом компоненте.

Контейнер изображен на рис. 5.


Рис.5

Компонентная модель

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

Компоненты EJB имеют, вольно выражаясь, два внешних описания (интерфейса). Через них, собственно, клиент и взаимодействует с Вашим компонентом. Пример этого изображен на рис. 6

Рис.6

Home-интерфейс, является точкой входа в Ваш компонент или фабрикой компонента. Другими словами любое начало взаимодействия с Вашими компонентами происходит через Home-интерфейсы. Клиент обращается к интерфейсу и создает через него экземпляры (объекты), которые обслуживают данный компонент. А в конце своей работы он их уничтожает.

Remote-интерфейс позволяет взаимодействовать с экземплярами (объектами), которые были созданы через фабрику (Home-интерфейс). Через Remote-интерфейс пользователь вызывает бизнес-методы компонента, которые естественно Вам придется реализовывать, запихивая туда логику Вашего приложения.

Разберем стандартный сценарий взаимодействия клиента с компонентами EJB. Взаимодействие изображено на рис. 7

Рис.7

1: Клиент ищет Home-интерфейс нужного ему компонента по его имени через сервис имен JNDI (клиенту возвращается в результате поиска Home-интерфейс этого найденного компонента).

2: Клиент, через найденный Home-интерфейс, вызывает функцию создания экземпляра компонента на стороне сервера (клиенту возвращается Remote-интерфейс созданного экземпляра компонента).

2.1: Сервер создает этот экземпляр.

3: Клиент вызывает бизнес-метод на созданном компоненте через его Remote-интерфейс этого компонента.

3.1: Сервер вызывает бизнес-метод на конкретном экземпляре компонента.

На стороне клиента Remote-интерфейс и Home-интерфейс оформлены в виде классов, которые скрывают сетевые взаимодействия на основе RMI с сервером приложений. Клиент работает с объектами, думая, что они работают в том же адресном пространстве, что и само приложение, а на самом деле происходят сетевые вызовы и функционал объектов работает совсем на другой вычислительной машине.

Home-интерфейс

Как уже говорилось выше, вся работа с компонентами начинается с обращения к Home-интерфейсу. Каждый тип компонент должен его иметь. Пример Home-интерфейса изображен на рис. 8.

Рис.8

В этом интерфейсе Вы должны определить методы двух типов. Это фабричные методы create и поисковые find.

Фабричные методы позволяют Вам создавать для себя экземпляры компонентов на стороне сервера. При вызове этого метода Вы можете передать параметры инициализации компонента. Можно иметь несколько фабричных методов с разным числом параметров. При вызове фабричного метода Вам возвращается ссылка созданного компонента на стороне сервера. Получив эту ссылку, Вы можете начать общение с созданным компонентом, т.е. Вызывать его бизнес методы.

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

Remote-интерфейс

После того, как Вы создали или нашли компонент через его Home-интерфейс и получили ссылку на его Remote-интерфейс, можно приступить к взаимодействию с этим EJB-компонентом. Все способы взаимодействия с компонентом строго определены в полученном Remote-интерфейсе. Пример Remote-интерфейса изображен на рис. 9

Рис.9

Стандартом, конечно, являются get/set-методы, считывающие и устанавливающие состояния параметров EJB-компонентов. Можно определить любые методы в Remote-интерфейсе, например пересчета суммы из одной валюты в другую по такому-то курсу второй валюты относительно первой.

Реализация компонента

После того как Вы определили Home и Remote интерфейсы своего компонента, необходимо написать реализации методов определенных в них. К некоторым методам в реализации добавляется приставка ejb. Пример реализации выше рассмотренного компонента показан на рис. 10.

Рис.10

Кратко опишу, зачем нужны все показанные методы и параметры, а также коснусь примерной их реализации:

  • ctx - ссылка на объект, которая позволяет компоненту получать служебную информацию о пользовательских транзакциях и данные о том какой пользователь работает с компонентом.
  • ds - ссылка на пул соединений с базой данных.
  • name, title, description, jndi, port - параметры компонента доступные через методы Remote-интерфейса
  • serverHome - ссылка на Home-интерфейс компонента Server (не заостряйте свое внимание на этом, так как она всплыла в примере случайно).
  • setEntityContext/unsetEntityContext - методы, в которых устанавливается ctx. Вызываются только контейнером.
  • ejbActivate/ejbPassivate - методы управляющие жизненным циклом компонента. Вызываются только контейнером.
  • ejbRemove - метод который вызывается перед уничтожением компонента на стороне сервера. Для сущностного бина, например, реализует запрос в базу данных на удаление этого компонента из базы.
  • getConnection - метод который вызывают для взятия соединения из пула соединений (см. ds). Его определяют больше для удобства и он к спецификации EJB не имеет ни какого отношения.
  • ejbCreate - методы которые реализует create методы из Home-интерфейса. Например, для сущностных бинов в нем реализуют запрос к базе данных для создания компонента и в нем устанавливают параметры компонента.
  • ejbPostCreate - методы вызываются после ejbCreate. Как использовать эту возможность я не смог придумать и обычно реализация этого метода пуста.
  • ejbFind - методы реализуют find методы определенные в Home-интерфейсе и производят поиск компонентов в базе данных.
  • get/set - методы реализуют get/set методы определенные в Remote-интерфейсе.
  • toString - определен для пущей совместимости с инфраструктурой JAVA. Если, ни дай Бог, кому-то, например, приспичит через System.out.println посмотреть с каким это компонентом сейчас работает программа... К спецификации EJB не имеет ни какого отношения.

Дерево имен JNDI

JNDI (Java Naming Directory Interface). Расскажу немного подробнее об этом сервисе. Приведу хорошую аналогию. Мы постоянно пользуемся службой DNS не задумываясь как она работает и почему она появилась. Для тех кто плохо ориентируется в DNS я сейчас поясню основную идею. Как уже всем известно каждый компьютер подключенный к сети Internet имеет свой уникальный IP адрес. Например 213.10.2.4 или 194.145.90.158. Запоминать такие адреса человеку чаще всего сложно. И придумали сопоставлять каждому IP адресу определенное составное имя. Например kooper.favour.com или beta.alpha.rest.com. Такие имена значительно проще запомнить человеку. К тому же читая имя справа налево человек может видеть иерархию имен, т.е. есть сервер com к нему подключен сервер favour, а к favour подключен kooper. Конечно такая иерархи чаще всего условная и не имеет никакого отношения к реальному положению дел, но этот механизм позволяет примерно понять какой фирме принадлежит компьютер с таким именем. Побочным эффектом такого подхода стала очень интересная и удобная вещь. Так как теперь все используют имена в место конкретных IP адресов, в случае смены IP адреса не нужно оповещать всех об этом. Нужно только поменять соответствие между именем и IP адресом. Вы это бы хорошо оценили если бы у Вас был бы популярный Web-портал и в один прекрасный момент порталу перестало бы хватать пропускной способности канала провайдера и вам срочно нужно сменить старого интернет провайдера на нового и не хотелось бы терять посетителей которые помнят Ваш IP адрес, т.к. новый провайдер выдаст вам новый IP адрес. А тут все просто. Смени у имени в DNS старый IP адрес на новый. И пользователи Вашего портала ничего не заметят.

А теперь вернемся к службе JNDI. Каждому компоненту EJB сопоставляется имя, которое публикуется на дереве имен JNDI. И клиентское приложение обращается к этой службе зная имя под которым зарегистрирован EJB компонент. Обратившись к службе имен клиентское приложение получает по имени объектную ссылку. На самом деле существует менее изящный способ получения объектной ссылки. Но для начала я думаю необходимо пояснить, что такое объектная ссылка. Так как изначально полагается что компоненты работают в разных адресных пространствах с клиентским приложением, т.е. в разных виртуальных машинах и все их взаимодействие является сетевым, то не совсем понятно что такое объектная ссылка в этом случае. Классически объектная ссылка это можно сказать адрес в памяти, но в случае удаленного взаимодействия это адрес хоста, номер порта, плюс много всякой служебной информации и плюс еще к тому что эта объектная ссылка уникальная и ее значение не возможно предсказать. Самым первый способ получения объектной ссылки выглядит так: запускается компонент на стороне сервера и полученная объектная ссылка записывается в файл и передается на сторону клиента. Можно ее перенести на дискете или передать по FTP или получить с web сервера по http. Не очень красивое решение. Сервис именования JNDI позволяет по имени получить объектную ссылку компонента. Сценарий запуска сервера и взаимодействия клиента уже выглядит следующим образом: запускается компонент на стороне сервера, который себя регистрирует на дереве имен JNDI под заранее оговоренным с клиентом именем, а потом клиентское приложение через сервис JNDI по имени получает объектную ссылку на этот компонент.

Еще одним преимуществом использования сервиса JNDI проявляется в следующей ситуации. Предположим Вы разработали 6 компонентов EJB, эти компоненты общаются с друг другом для выполнения запросов поступающих со стороны клиентского приложения. И вот настал тот долгожданный день, когда Ваш сервер приложений перестал справляться с вычислительной нагрузкой. И вот Вы решили компоненты EJB разместить на 3 серверах предложений. Переход от одного сервера приложений к трем изображен на рис. 11.

Рис.11

Как видно из рисунка, все компоненты EJB зарегистрированы на сервисе JNDI и при взаимодействии сначала ищут друг друга на JNDI. В случае когда их разместили на разных серверах приложений, компоненты даже ничего не заметили так как доступ к соседним компонентам получали через сервис JNDI. И естественно клиентское приложение, тоже ничего не почувствовало. Что же мы получаем в итоге? Мы распределили наши компоненты на разные вычислительные машины и при этом не изменили ни одной строчки кода ни в клиентском приложении ни в самих компонентах.


Сессионные бины

Сессионный бин по функциональности очень похож на обычный класс, от которого вы можете порождать объекты и использовать. Отличительной чертой является способ создания объекта. Как уже говорилось выше существуют Home-интерфейс, который является точкой входа в ваш бин. В нем вы определяете метод create, через который можно создавать сессионные бины на стороне сервера. Вообще сессионные бины предназначены быть представителем клиента на стороне сервера или быть его функциональным расширением, другими словами они нужны в течении сессии работы клиента, а потом их уничтожают. Сессионный бин показан на рис. 12.

Рис.12

Вы можете объявить бизнес методы бина в Remote-интерфейсе(Test) и реализовать их в Implementation бина (TestBean). Другими словами из клиента вы будете вызывать методы Remote-интерфейса, а контейнер будет передавать управлению на реализацию бина сопоставленную с вашим обращением. Есть такое понятие как исполнитель, который сопоставляется бину и обеспечивает его функциональные возможности. Это понятие было введено, так как бин является больше абстракцией, которую нужно поддерживать реализацией. Контейнер управляет пулом исполнителей бинов и решает, какому из исполнителей передать управления. Таким образом, обеспечивается равномерное распределение нагрузки между исполнителями.

Сессионные бины бывают двух видов: Stateless and Stateful. Другими словами бины могут не помнить свое состояние и помнить.

Сессионный бин не помнящий свое состояние

Бывает ситуации, когда Вам не нужно, что бы бин помнил свое состояния между двумя вызовами методов, т.е. вы не складываете информацию в бин методами set и в последующем не пытаетесь ее запросить методами get. Указав, что ваш бин является Stateless вы даете возможность контейнеру лучше использовать ресурсы вычислительной машины при обработки запросов к такой разновидности сессионного бинов.

Сессионный бин помнящий свое состояние

Бывает ситуации, когда Вам нужно, что бы бин помнил свое состояния между двумя вызовами методов, т.е. вы складываете информацию в бин методами set и в последующем пытаетесь ее запросить методами get. Указав, что ваш бин является Stateful вы обязываете контейнер производить сериализацию на исполнителе, когда серверу не хватает ресурсов для обработки запросов пользователей и контейнер решает сопоставить не занятого исполнителя с запросом пользователя, то ему необходимо сначала сериализировать его состояние. А если попроще, то давайте представим две центрифуги. В каждой из них лежит грязное белье пользователя. Две центрифуги и два пользователя. Предположим что оба пользователя включили режим стирки. Стирка закончилась в первой центрифуге. Первый пользователь пока еще размышляет включить ему режим отжима или так свое белье забрать. В этот момент приходит третий пользователь, а центрифуги всего две. Подходит владелец прачечной и вытаскивает не отжатое белье первого пользователя и помещает белье третьего и запускает центрифугу. После стирки белья третьего пользователя, отжимается белье второго, а потом и третьего пользователя. Выходит что центрифуги две, а пользователя три. Для того, что бы это работало нужно доставать и обратно класть белье, этот процесс называется сериализацией. Или говоря научным языком в случае, когда исполнителей не хватает, то контейнер просто сериализирует состояние одного из исполнителей, передает управление на него, а когда настоящий владелец сериализированного исполнителя пытается на нем вызвать бизнес метод, контейнер производит сериализацию состояния другого исполнителя и восстанавливает состояние сериализированного бина. Сериализация состояния бина происходит обычно на винчестер.

Жизненный цикл сессионных бинов

Разберем жизненный цикл Stateless сессионного бина. Жизненный цикл изображен на рис. 13.

Рис.13

Жизненный цикл сессионного бина не помнящего своего состояния довольно прост. Всего два возможных состояния это когда еще ejbObject не существует и когда он создан и помещен в пул. Контейнер не ставит строго соответствия между конкретным клиентом который вызывает бизнес метод и конкретным исполнителем. Обычно для обработки бизнес метода берется тот исполнитель, который "не занят".

Разберем жизненный цикл в Stateful сессионного бина. Жизненный цикл изображен на рис. 14.

Рис.14

Жизненный цикл сессионного бина помнящего своего состояния несколько посложнее. В принципе он похож на предыдущей, только с одним расширением, т.к. необходимо строго сопоставлять клиента с его сессионным бином вводится понятие активизации и пассивизации бина. Во время сопоставления клиента с его сессионным бином необходимо провести активацию, т.е. реализуя метод ejbActivate вы можете в нем определить открытия например сетевых соединений, которые использует бин и когда контейнер решает воспользоваться этим бином что бы обслужить другого пользователя, то происходит сначала пассивизация, которую вы можете реализовать в методе ejbPassivate например закрытия тех соединений которые вы открыли, а потом и активация соответственно. Метод ejbActivate вызывается сразу после сериализации, а метода ejbPassivate до сериализации.

Транзакции в сессионных бинах

Как не странно это звучит, сессионные бины могут участвовать в транзакциях. Есть такое понятие, как транзактивный контекст. Другими словами бизнес методы сессионного бина могут выполнятся в транзактивном контексте. Это значит, что если вы начнете транзакцию и вызовите метод какого-либо сессионного бина, то бин на котором будет вызван этот метод будет вовлечен в транзакцию и будет в текущем (вашем) транзактивном контексте. Если вы решите зафиксировать (commit) свои действия, то координатор транзакций использует ваш транзактивный контекст для этих целей что бы узнать какие бины участвовали в транзакции и сообщить им о завершении транзакции. С другой стороны сессионый бин может обратиться к сессионному контексту что бы узнать участвует он в транзакции или нет. Также во время выполнения бизнес метода, бин может решить что выполнение происходит с ошибкой и сказать транзактивному контексту что бы был произведен откат (rollback) транзакции.

Выше я описал случай когда транзакции управляются самим бином. Но есть второй режим когда транзакцией управляет сам контейнер и естественно теряется гибкость. Не буду тут пояснять второй случай что бы не запутать читателя. Второй случай будет объяснен далее.

Сущностный бин

Идея заложенная в сущностные бины следующая. Нам приходится хранить информацию в реляционных таблицах и обеспечить к ним гибкий доступ используя ООП. Есть реляционная таблица на нее нужно создать сущностный бин. Реализация сущностного бина соответствует строчки в базе данных. Сессионный бин изображен на рис. 15

Рис.15

Покажу точки соприкосновения ООП с SQL-запросами. В ejbCreate происходит INSERT, в ejbRemove - DELETE, в ejbStore - UPDATE, в ejbLoad - SELECT. На рисунке показан пример бина, который обслуживает таблицу всего с двумя столбцами PK и title. Также присутствуют поисковые методы ejbFind, которые позволяют выдергивать идентификаторы объектов из базы данных, но не отвечают за загрузку их состояний в память. Кстати, процесс перехода из строчки таблицы в объект называется материализацией, а сохранения объекта в строчку таблицы - дематериализацией. Механизм взаимодействия с сущностными бинами такой же как с сессионными, за исключением того, что на HOME-интерфейсе появляются Find-методы, которые не создают объекты в базе данных, а находят что бы с ними можно было работать. Архитектура сущностного бина отличается понятием основной ключ Primary Key, который представлен в нашем примере как класс EntityPK. Этот класс обворачивает основной ключ таблицы, которую обслуживает бин.

Источник данных DataSource

В реализации сущностного бина необходим, что бы посылать SQL-запросы использовать соединение с БД. Был придумал пул соединения с БД (DataSource). Это было сделано что бы не тратить ресурсы и время на создания новых соединений с БД. Создаются соединения через DataSource и когда бин перестает его использовать, соединения не закрывают а держат в пуле и когда другой бин просит соединение то ему отдают давно уже созданное соединение. На самом деле процесс несколько сложнее из-за транзакций, но идея изложенная выше верна.

Механизм сохранения управляемый бином

Можно самому в реализации бина прописать все взаимодействия с БД. Такой подход называется механизмом сохранения управляемый бином (Bean-Managed Persistence). Лично я считаю, что таким образом можно добиться более эффективных и гибких решений. Особенно Вы это начнете понимать когда вам в ТЗ напишут что бы бины были совместимы с 4-мя типами СУБД.

Механизм сохранения управляемый контейнером

Используя этот механизм, программист описывает в дескрипторе описания бина имя таблицы и типы ее столбцов. После этого добавляет get/set методы в реализацию бина, а механизмом синхронизации бина с БД управляет уже сам контейнер. Таким образом время разработки бина сокращается в несколько раз. Такой механизм называется Container-Managed Persistence.

Атрибут транзактивности бина

Атрибуты транзактивности бина нужны только в том случае если транзакции управляются самим бином. Бывают следующие транзактивные атрибуты Required, RequiresNew, Mandatory, NotSupported, Supports, Never. Один из этих атрибутов вы указываете в XML описании вашего бина на каждый ваш бизнес метод или на все методы сразу. На сама деле этот атрибут говорит контейнеру, что делать с транзактивным контекстом в случае вызова бизнес метода на бине. Например: если был вызван метод не в транзакции, то начать новую транзакцию или если если вызван в транзактивном контексте, то создать свою транзакцию и выполнять метод в ней. И таких вариаций много. Для полного описания обратитесь к спецификации или к документации компании у который вы купили сервер приложений.

Четыре уровня изоляции транзакции

Обычно технологию EJB применяют для систем, к которым предъявлены высокие требования. И волей-неволей Вам придется столкнутся с проблемой изоляции транзакций

TRANSACTION_READ_UNCOMMITED

С таким уровнем изоляции транзакции вы будете видеть изменения, которые происходят в соседней транзакции до того как она либо успешно завершится или откатится. Эта проблема называется грязным чтением.

TRANSACTION_READ_COMMITED

Этот уровень Вас избавит от грязного чтения.

TRANSACTION_REPEATABLE_READ

Этот уровень вас избавит от проблемы неповторимого чтения. Это возникает тогда, когда вы во время транзакции считали какую-то строчку, а через некоторое время считали ее еще раз в той же транзакции и обнаружили, что она была изменена в другой транзакции. С таким уровнем изоляции вы избавитесь от этой проблемы. Просто, что вы будете считывать в одной транзакции будет блокировано на измненние в другой пока вы не закончите первую.

TRANSACTION_SERIALIZABLE

Этот уровень избавит от фантомной проблемы. Предположим в одной транзакции вы запросили список строк и через некоторое время сделали повторный запрос и получили на одну строку больше. Для того что бы этого не случилось используйте этот уровень изоляции транзакции. Следует помнить, чем выше уровень изоляции транзакции тем больше требует это вычислительных ресурсов у СУБД.

Жизненный цикл сущностных бинов

Жизненный цикл (ЖЦ) сущностных бинов похож на сессионный, но несколько сложнее. Жизненный цикл изображен на рис.16

Рис.16

Скажу честно, что бы вы поняли, как это работает вам потребуется очень хорошо изучить архитектуру EJB, так что я в свое статье коснусь только основной мысли. В ЖЦ сущностного бина добавились два события это вызов методов ejbLoad и ejbStore, которые синхронизируют состояние бина с состоянием БД. Метод ejbLoad вызывается, когда бин попадает в транзакцию, а ejbStore когда транзакция завершается.



Метки: ejb
Комментарии: 5 Просмотров: 8653 [История изменений] Размер:61140 байт
Последние изменения сделаны: evgeny Евгений Игумнов 24 дня назад 09.08.2010 23:04:13
ДобавилТекст

Anonymous
вопрос
1544 дня назад 12.06.2006 05:56:02 Цитата('2','88','7','1893')">Сообщить о спаме

спасибо за текст, в первую очередь.
а во-вторых, в разделе "Сущностный бин" в конце первого абзаца есть предложение "Сессионный бин изображен на рис. 15" - это опечатка или нет?




Pavel
273 дня назад 03.12.2009 23:28:36 Цитата('2','88','7','5410')">Сообщить о спаме

Спасибо! отличная статья! Это 4-ая статья про "EJB для чайноиков", которую я прочитал, и она определенно самая лучшая! Жаль нет кнопки "версия для печати" =(


Ivan
Спасибо за статью
255 дней назад 22.12.2009 03:13:27 Цитата('2','88','7','5434')">Сообщить о спаме

Очень хорошо написана. Вот бы увидеть более полную и подробную версию...


Vanger
234 дня назад 12.01.2010 05:13:38 Цитата('2','88','7','5452')">Сообщить о спаме

Большое спасибо.

Статья позволила аккуратно уложить всё в памяти.


msangel
24 дня назад 09.08.2010 23:04:13 Цитата('2','88','7','6222')">Сообщить о спаме

Спасибо за такую хорошую статью. Однако хотелось немного детальнее. Я думаю что тот, кому нужно - прочтет. 


Введите код на картинке 
Ваше имя 
E-mail 
(видим лишь владельцу сайта)
WWW 

Тема

В тексте можно использовать Wiki или HTML теги



Жалоба | © Kolobok smiles, Aiwan