Продолжается подписка на наши издания! Вы не забыли подписаться?

Работа с СУБД в IBM WebSphere Community Edition

Автор: Александр Цимбал
Опубликовано: 03.07.2006

Взаимодействие с СУБД – важная и существенная часть большинства приложений, и не только в архитектуре клиент-сервер. Использование API для взаимодействия с СУБД характерно и для серверов приложений (даже в случае использования компонентной модели EJB), и для клиентских приложений – для временного хранения данных на стороне клиента, например, в случае невозможности поддержания непрерывного соединения с сервером.

Как и любая другая Java-ориентированная технология, J2EE в качестве основного инструмента взаимодействия с РСУБД полагается на JDBC, точнее, JDBC версии 2.1 и выше.

JDBC и J2EE

Для понимания механизма взаимодействия WAS CE c СУБД необходимо знать основы JDBC.

То, что JDBC построен по драйверному принципу, известно всем. К сожалению, те фундаментальные возможности JDBC, которые и позволяют этой технологии успешно взаимодействовать с другими технологиями в составе J2EE, знакомы немногим. Причина проста – эти возможности редко «попадаются на глаза». Как говорилось в эпиграфе к одной из глав книги М. Твена «Простофиля Вильсон», «на поверхности он бесполезен. Он должен находиться под землей и вдохновлять капусту».

JDBC 1.0 поддерживал только физические соединения с серверами БД. Это означало, что установка и разрыв соединения были связаны с существенными затратами ресурсов. Кроме того, не поддерживалось взаимодействие с внешними координаторами объектных транзакций – JDBC 1.0 поддерживал только локальные транзакции – транзакции на уровне одного физического соединения с БД. Наконец, менеджер соединений в JDBC 1.0 невозможно было сделать доступным для других элементов распределенной системы с помощью JNDI. Другими словами, JDBC 1.0 справлялся с задачами, характерными для архитектуры «клиент-сервер», но не удовлетворял требованиям, предъявляемым многозвенными системами.

Ответом на эти требования стала разработка стандарта JDBC 2.0 (точнее, JDBC 2.1). Основными ключевыми изменениями были следующие: менеджер соединений (интерфейс DataSource и производные от него интерфейсы) можно опубликовывать и, соответственно, получать с помощью JNDI и, самое главное, соответствующий JDBC-драйвер должен уметь поддерживать пулы соединений с СУБД, а также сопоставлять соединение с объектной распределенной (глобальной) транзакцией.

Несмотря на возможности, предоставляемые современными JDBC-драйверами, разработчикам J2EE для решения ряда задач требуется поддерживать более тесное взаимодействие с соединениями БД, нежели позволяет JDBC. Примером может служить необходимость координации глобальных (на уровне координатора объектных транзакций распределенной системы) и локальных (на уровне соединения JDBC) транзакций. Поскольку программист может самостоятельно вызывать методы API JDBC, в том числе и методы управления локальными транзакциями (такими, как setAutoCommit() или commit()), возникает возможность рассогласованного поведения при наличии глобальных транзакций. Спецификация J2EE требует, чтобы реализация предоставила возможность управления локальными транзакциями при наличии глобальных, а для этого нужно иметь возможность перехвата на уровне контейнера EJB-компонентов явного – и ошибочного – вызова разработчиком методов управления локальными транзакциями. Кроме того, драйвера JDBC 1.0 еще недавно использовались очень широко, и нужно было предусмотреть возможность их использования при работе J2EE-серверов приложений.

Был найден следующий выход: создание и поддержка пула соединений, выбор нужного вида соединения, сопоставление соединения с контекстом глобальной транзакции в большинстве случаев выполняется не JDBC-драйвером, а специальным программным модулем в составе самого J2EE-сервера приложений. Собственно драйвер используется тогда, когда нужно получить физическое соединение с СУБД, а также для поддержки распределенных транзакций (XA-транзакций).

Поддержка пула соединений в WAS CE

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

Как следствие, в состав дистрибутива WAS CE 1.0.1 входит несколько реализаций пула соединений и управления транзакциями. Работа со всеми этими реализациями происходит одинаково, поэтому в примерах мы будем использовать универсальную реализацию для поддержки локальных транзакций.

Эта реализация выполнена в виде стандартного ресурсного адаптера J2EE – модуля с расширением RAR. Этот файл имеет имя tranql-connector-1.1.rar и находится (вместе с другими реализациями пула соединений) в каталоге <install_dir>\repository\tranql\rars. Его развертывание на сервере, как и любого другого модуля, требует наличия xml-дескриптора. В этом xml-дескрипторе и указываются все необходимые для нормальной работы пула параметры.

Первый вопрос, на который должен дать ответ разработчик приложения, взаимодействующего с БД, таков: какова должна быть «область видимости» создаваемого пула соединений?

При разработке серверных приложений возможны два ответа:

Создание клиентских приложений для WAS CE – тема для отдельной статьи.

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

Выбор и подключение JDBC-драйвера

Для нормальной работы с БД с использованием WAS CE необходимо иметь соответствующий JDBC-драйвер. JDBC-драйвера бывают разных типов – написанные на Java или с использованием native-кода, поддерживающие двухфазные (XA) транзакции и нет, обеспечивающие сетевое соединение с СУБД или требующие для работы дополнительного ПО. Сейчас в большинстве случаев используются JDBC-драйверы так называемого четвертого типа. Они поставляются в виде jar-файлов.

WAS CE содержит JDBC-драйвера для большого количества распространенных СУБД. В настоящий момент WAS CE «понимает» – т.е. либо содержит нужный драйвер, либо обеспечивает помощь в его поиске, загрузке и настройке – следующие наиболее популярные типы СУБД (это не полный список):

Разработчик может использовать доступные ODBC-драйвера (через мост JDBC-ODBC).

Кроме того, в состав WAS CE входит встроенная СУБД Derby (это клон БД Cloudscape), которая создавалась в рамках open-source проекта.

Многие из перечисленных СУБД поддерживаются как в локальном, так и в XA-режиме, т.е. режиме использования распределенных транзакций.

Несколько слов о поддержке встроенной БД Derby. Она используется сервисами самой WAS CE и готова к работе сразу после установки WAS CE. Derby поддерживается в различных режимах, в том числе режиме использования XA-транзакций. Поскольку она играет особую роль, консоль администратора в панели навигации (левая часть консоли) содержит специальный пункт – «Embedded DB». С помощью средств консоли («DBManager») пользователь может создавать новые БД, интерактивно создавать и выполнять SQL-операторы для выбранной БД Derby, а также получить список параметров настройки этой СУБД («DB Info»).

В приведенном в этой статье примере приложения будет использоваться не Derby, а бесплатная версия СУБД DB2 – DB2 Express C, которую можно бесплатно скачать с сайта IBM (http://www-306.ibm.com/software/data/db2/ udb/db2express/download.html).

JDBC-драйверы (их jar-файлы) должны находиться в каталоге repository (точнее, одном из его подкаталогов) каталога установки WAS CE. Например, JDBC-драйвер для Derby находится в каталоге <install_dir> \repository\org.apache.derby\jars, а драйвер для DB2 ExpressC – в каталоге <install_dir> \repository\com.ibm.db2\ jars.

Если разработчик хочет для создания и настройки использовать JDBC-драйвер, не входящий в комплект поставки WAS CE, то он должен поместить этот драйвер в подкаталог каталога \repository. Обратите внимание, что эксперты консоли администратора WAS CE полагаются на определенное соглашение об именах для jar-файлов. В частности, имя jar-файла обязательно должно содержать номер версии и подверсии драйвера. Например, jar-файл для драйвера DB2 ExpressC имеет имя db2jcc-8.2.jar, а jar-файл для одного из Derby-драйверов – derby-10.1.2.ibm.jar, причем номер версии отделяется от имени дефисом.


Рисунок 1.


Рисунок 2.

Создание пула с помощью консоли администратора

Если нужно создать пул соединений уровня сервера – т.е. пул, доступный всем приложениям этого сервера – то наиболее удобно сделать это с помощью консоли администратора, которая содержит специального мастера (wizard) для решения этой задачи. Чтобы вызвать его, в панели навигации консоли нужно выбрать пункт «Database Pools». Можно либо создавать пул соединений «с нуля» (мастер «Using the Geronimo database pool wizard»), либо импортировать готовый пул, созданный при работе с другими серверами – JBoss или Weblogic. В данной статье мы будем создавать пул соединений с DB2 ExpressC.

На первом шаге при использовании данного мастера разработчик должен выбрать имя создаваемого пула и тип используемой БД (рисунок 1).

Имя пула должно быть уникальным на сервере среди имен всех других ресурсов. Это имя появится в специфическом для WAS CE дескрипторе развертывания – там, где необходимо будет сопоставить выбранное разработчиком JNDI-имя и имя реального ресурса.

После выбора одного из поддерживаемых мастером типов БД нужно перейти к следующему этапу (рисунок 2).

Имя класса драйвера определяет сам мастер, хотя пользователь может его изменить «вручную». Jar-файл, содержащий код драйвера, нужно выбрать из списка. Если в этом списке нет соответствующего драйвера, можно попробовать найти его и загрузить с помощью мастеров консоли (кнопка «Download a driver»).

Дальнейшие параметры зависят от того, как был сконфигурирован установленный экземпляр СУБД, к которому выполняется обращение.

Наконец, на последнем шаге работы с мастером разработчик окончательно формирует нужный URL (URL формируется на основе ранее введенных данных, но здесь его можно изменить) и задает параметры – минимальный (0 по умолчанию) и максимальный (10 по умолчанию) размер пула, время ожидания (в мсек, 5000 по умолчанию) до возбуждения исключения в случае, когда пользователь запрашивает соединение, но свободных соединений в пуле нет, и время ожидания (в минутах, 15 по умолчанию) до удаления из пула неиспользуемого соединения и уменьшения его текущего размера.

После задания всех параметров имеет смысл проверить настройку пула – установить соединение с СУБД (кнопка «Test Connection»). Если все хорошо, появится страница с соответствующей информацией (рисунок 3).

Теперь можно выполнить развертывание созданного пула на сервере (кнопка «Deploy» на шаге 4 или кнопка «Skip test and deploy» на предыдущем шаге). Полезной – особенно при создании пула «вручную», о чем речь пойдет в следующем разделе – может оказаться кнопка «Show Plan» (или «Skip Test an Show Plan» на предыдущем шаге), которая приводит к отображению сгенерированного xml-дескриптора для развертываемого коннектора.


Рисунок 3.

Создание пула «вручную»

Термин «вручную» не надо понимать буквально – с учетом возможностей, предоставляемых мастерами консоли администратора. Здесь имеется в виду создание xml-файла, содержащего текст дескриптора, и некоторые манипуляции с этим файлом.

Для создания пула соединений уровня сервера приложений или корректировки параметров существующего пула всегда имеет смысл использовать консоль оператора – при этом в явном создании xml-файла дескриптора нет необходимости. Разумеется, даже при создании пула уровня сервера можно поступить иначе – создать xml-дескриптор, а затем с помощью командной строки развернуть пул на сервере. Этот подход может быть удобен, например, при использовании нетривиальных командных файлов. Командная строка для выполнения такого развертывания может выглядеть так:

 java -jar bin/deployer.jar deploy <имя_файла_дескриптора>.xml \
        repository/tranql/rars/tranql-connector-1.1.rar 

Данный вид командной строки подразумевает, что текущим каталогом является каталог установки WAS CE.

Явное создание xml-файла дескриптора и размещение его в EAR-архиве необходимо в случае создания пула соединений на уровне J2EE-приложения, а не сервера. Для создания такого пула нужно выполнить следующие действия:

<application
  xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.0"
    configId="MyApplication">
  <module>
    <connector>имя_RAR_файла.rar</connector>
    <alt-dd>имя_XML_дескриптора.xml</alt-dd>
  </module>
</application>

Теперь осталось только ознакомиться с кодом дескриптора пула соединений (его вид не зависит от области видимости пула – на уровне сервера или на уровне приложения).


Рисунок 4.

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

<?xml version="1.0" encoding="UTF-8"?>
<connector configId="console-db-pool-MyDatabaseSource" xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.0">
  <dep:dependency xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.0">
    <dep:uri>com.ibm.db2/db2jcc/8.2/jar</dep:uri>
  </dep:dependency>
  <resourceadapter>
    <outbound-resourceadapter>
      <connection-definition>
        <connectionfactory-interface>
          javax.sql.DataSource
        </connectionfactory-interface>
        <connectiondefinition-instance>
          <name>
            MyDatabaseSource
          </name>
          <config-property-setting name="Password">
            adminpassword
          </config-property-setting>
          <config-property-setting name="Driver">
            com.ibm.db2.jcc.DB2Driver
          </config-property-setting>
          <config-property-setting name="UserName">
            db2admin
          </config-property-setting>
          <config-property-setting name="ConnectionURL">
            jdbc:db2://localhost:50000/MYDEMODB
          </config-property-setting>
          <connectionmanager>
            <local-transaction/>
            <single-pool>
              <max-size>10</max-size>
              <min-size>0</min-size>
              <match-one/>
            </single-pool>
          </connectionmanager>
        </connectiondefinition-instance>
      </connection-definition>
    </outbound-resourceadapter>
  </resourceadapter>
</connector>

Обратить внимание стоит на следующее:

<...>

Заключение

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

........................
"С полным содержанием данной статьи можно ознакомиться в печатной версии журнала"

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

Copyright © 1994-2016 ООО "К-Пресс"