Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел покрытия DataSource
объекты, которые являются привилегированными средствами получения соединения с источником данных. В дополнение к их другим преимуществам, которые будут объяснены позже, DataSource
объекты могут обеспечить объединение в пул соединения и распределенные транзакции. Эта функциональность важна для вычислений базы данных предприятия. В частности это является неотъемлемой частью Предприятия JavaBeans (EJB) технология.
Этот раздел показывает Вам, как получить соединение, используя DataSource
взаимодействуйте через интерфейс и как использовать объединение в пул соединения и распределенные транзакции. Оба из них включают очень немного изменений кода в Ваше приложение JDBC.
Работа, выполняемая, чтобы развернуть классы, которые делают эти операции возможными, который системный администратор обычно делает с инструментом (таким как Tomcat Apache или Oracle Сервер WebLogic), меняется в зависимости от типа DataSource
объект, который развертывается. В результате большая часть этого раздела посвящается показу, как системный администратор устанавливает среду так, чтобы программисты могли использовать a DataSource
объект получить соединения.
Следующие темы затрагиваются:
В Установлении Соединения Вы изучили, как получить соединение, используя DriverManager
class. Этот раздел показывает Вам, как использовать a DataSource
объект получить соединение с Вашим источником данных, который является привилегированным путем.
Объекты, которые инстанцируют классы, которые реализуют DataSource
представьте определенный DBMS или некоторый другой источник данных, такой как файл. A DataSource
объект представляет определенный DBMS или некоторый другой источник данных, такой как файл. Если компания будет использовать больше чем один источник данных, то она развернет отдельное DataSource
объект для каждого из них. DataSource
интерфейс реализуется поставщиком драйвера. Это может быть реализовано тремя различными способами:
DataSource
реализация производит стандарт Connection
объекты, которые не объединяются в пул или используются в распределенной транзакции.DataSource
реализация, которая поддерживает объединение в пул соединения, производит Connection
объекты, которые участвуют в объединении в пул соединения, то есть, соединения, которые могут быть переработаны.DataSource
реализация, которая поддерживает распределенные транзакции, производит Connection
объекты, которые могут использоваться в распределенной транзакции, то есть, транзакция что доступы два или больше сервера DBMS.Драйвер JDBC должен включать, по крайней мере, основное DataSource
реализация. Например, DB Java драйвер JDBC включает реализацию org.apache.derby.jdbc.ClientDataSource
и для MySQL, com.mysql.jdbc.jdbc2.optional.MysqlDataSource
.
A DataSource
class, который поддерживает распределенные транзакции обычно также, реализует поддержку объединения в пул соединения. Например, a DataSource
class, обеспеченный поставщиком EJB почти всегда, поддерживает и объединение в пул соединения и распределенные транзакции.
Предположите, что владелец процветающей цепочки магазинов Перерыва на кофе, от предыдущих примеров, решил расшириться далее, продавая кофе по Интернету. С большим количеством онлайнового ожидаемого бизнеса владелец будет определенно нуждаться в объединении в пул соединения. Открытие и заключительные соединения включает много издержек, и владелец ожидает, что эта система заказа онлайн требует значительного числа запросов и обновлений. С объединением в пул соединения пул соединений может использоваться много раз, избегая расхода создания нового соединения для каждого доступа к базе данных. Кроме того, у владельца теперь есть второй DBMS, который содержит данные для недавно полученной компании жаренья кофе. Это означает, что владелец будет хотеть быть в состоянии записать распределенные транзакции, которые используют и старый сервер DBMS и новый.
Цепочечный владелец реконфигурировал компьютерную систему, чтобы служить новой, большей клиентской базе. Владелец купил новый драйвер JDBC и сервер приложений EJB, который работает с ним, чтобы быть в состоянии использовать распределенные транзакции и получить увеличенную производительность, которая идет с объединением в пул соединения. Много драйверов JDBC доступны, которые являются совместимыми с недавно купленным сервером EJB. У владельца теперь есть трехуровневая архитектура с новым сервером приложений EJB и драйвером JDBC в среднем уровне и двух серверах DBMS как третий уровень. Клиентские компьютеры, обращающиеся с просьбами, являются первым уровнем.
Системный администратор должен развернуться DataSource
объекты так, чтобы команда программистов Перерыва на кофе могла начать использовать их. Развертывание a DataSource
объект состоит из трех задач:
DataSource
classВо-первых, рассмотрите самый основной случай, который должен использовать основную реализацию DataSource
интерфейс, то есть, тот, который не поддерживает объединение в пул соединения или распределенные транзакции. В этом случае есть только один DataSource
возразите что потребности, которые будут развернуты. Основная реализация DataSource
производит тот же самый вид соединений что DriverManager
class производит.
Предположите компанию, которая хочет только основную реализацию DataSource
купил драйвер от поставщика JDBC DB Access, Inc. Этот драйвер включает class com.dbaccess.BasicDataSource
это реализует DataSource
интерфейс. Следующая выборка кода создает экземпляр class BasicDataSource
и устанавливает его свойства. После экземпляра BasicDataSource
развертывается, программист может вызвать метод DataSource.getConnection
получить соединение с базой данных компании, CUSTOMER_ACCOUNTS
. Во-первых, системный администратор создает BasicDataSource
объект ds
использование конструктора по умолчанию. Системный администратор тогда устанавливает три свойства. Отметьте, что следующий код обычно быть выполненным инструментом развертывания:
com.dbaccess.BasicDataSource ds = new com.dbaccess.BasicDataSource(); ds.setServerName("grinder"); ds.setDatabaseName("CUSTOMER_ACCOUNTS"); ds.setDescription("Customer accounts database for billing");
Переменная ds
теперь представляет базу данных CUSTOMER_ACCOUNTS
установленный на сервере. Любое соединение, произведенное BasicDataSource
объект ds
будет соединение с базой данных CUSTOMER_ACCOUNTS
.
С набором свойств системный администратор может зарегистрироваться BasicDataSource
объект с JNDI (Именование Java и Интерфейс Каталога) именование службы. Определенная служба именования, которая используется, обычно определяется системным свойством, которое не показывают здесь. Следующая выборка кода регистрируется BasicDataSource
возразите и связывает это с логическим именем jdbc/billingDB
:
Context ctx = new InitialContext(); ctx.bind("jdbc/billingDB", ds);
Этот код использует API JNDI. Первая строка создает InitialContext
объект, который служит начальной точкой для имени, подобного корневому каталогу в файловой системе. Вторые партнеры строки, или связывает, BasicDataSource
объект ds
к логическому имени jdbc/billingDB
. В следующей выборке кода Вы даете службе именования это логическое имя, и это возвращается BasicDataSource
объект. Логическое имя может быть любой строкой. В этом случае компания решила использовать имя billingDB
как логическое имя для CUSTOMER_ACCOUNTS
база данных.
В предыдущем примере, jdbc
подконтекст под начальным контекстом, как каталог под корневым каталогом является подкаталогом. Имя jdbc/billingDB
походит на путь, где последний элемент в пути походит на имя файла. В этом случае, billingDB
логическое имя, которое дается BasicDataSource
объект ds
. Подконтекст jdbc
резервируется для логических имен, которые будут связаны с DataSource
объекты, таким образом, jdbc
всегда будет первая часть логического имени для источника данных.
После основного DataSource
реализация развертывается системным администратором, это готово к программисту использовать. Это означает, что программист может дать логическое имя источника данных, которое было связано с экземпляром a DataSource
class, и JNDI именование службы возвратят экземпляр этого DataSource
class. Метод getConnection
может тогда быть обращен это DataSource
объект получить соединение с источником данных это представляет. Например, программист мог бы записать следующие две строки кода, чтобы получить a DataSource
объект, который производит соединение с базой данных CUSTOMER_ACCOUNTS
.
Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/billingDB");
Первая строка кода получает начальный контекст как начальную точку для того, чтобы получить a DataSource
объект. Когда Вы предоставляете логическое имя jdbc/billingDB
к методу lookup
, метод возвращается DataSource
возразите что системный администратор, связанный с jdbc/billingDB
во время развертывания. Поскольку возвращаемое значение метода lookup
Java Object
, мы должны бросить это к более определенному DataSource
введите прежде, чем присвоить это переменной ds
.
Переменная ds
экземпляр class com.dbaccess.BasicDataSource
это реализует DataSource
интерфейс. Вызов метода ds.getConnection
производит соединение с CUSTOMER_ACCOUNTS
база данных.
Connection con = ds.getConnection("fernanda","brewed");
getConnection
метод требует только имени пользователя и пароля потому что переменная ds
имеет остальную часть информации, необходимой для того, чтобы установить соединение с CUSTOMER_ACCOUNTS
база данных, такая как имя базы данных и расположение, в его свойствах.
Из-за его свойств, a DataSource
объект является лучшей альтернативой чем DriverManager
class для того, чтобы получить соединение. Программисты больше не должны трудно кодировать имя драйвера или URL JDBC в их приложениях, который делает их более переносимыми. Кроме того, DataSource
свойства делают код поддержания намного более простым. Если есть изменение, системный администратор может обновить свойства источника данных и не быть обеспокоен изменением каждого приложения, которое делает соединение с источником данных. Например, если бы источник данных был перемещен в различный сервер, то весь системный администратор должен был бы сделать, устанавливается serverName
свойство к новому имени сервера.
Кроме мобильности и непринужденности обслуживания, используя a DataSource
объект получить соединения может предложить другие преимущества. Когда DataSource
интерфейс реализуется, чтобы работать с a ConnectionPoolDataSource
реализация, все соединения производятся экземплярами этого DataSource
class автоматически будет объединенными в пул соединениями. Точно так же, когда DataSource
реализация реализуется, чтобы работать с XADataSource
class, все соединения это, продукты автоматически будут соединениями, которые могут использоваться в распределенной транзакции. Следующий раздел показывает, как развернуть эти типы DataSource
реализации.
Системный администратор или другой человек, работающий в той емкости, могут развернуть a DataSource
возразите так, чтобы соединения это продукты были объединенными в пул соединениями. Чтобы сделать это, он или она сначала развертывает a ConnectionPoolDataSource
возразите и затем разверните a DataSource
объект, реализованный, чтобы работать с этим. Свойства ConnectionPoolDataSource
объект устанавливается так, чтобы он представил источник данных, для которого будут произведены соединения. После ConnectionPoolDataSource
объект был зарегистрирован в JNDI именование службы, DataSource
объект развертывается. Обычно только два свойства должны быть установлены для DataSource
объект: description
и dataSourceName
. Значение, данное dataSourceName
свойство является логическим именем, идентифицирующим ConnectionPoolDataSource
возразите ранее развернутый, который является объектом, содержащим свойства, должен был сделать соединение.
С ConnectionPoolDataSource
и DataSource
объекты развертывались, можно вызвать метод DataSource.getConnection
на DataSource
возразите и получите объединенное в пул соединение. Это соединение будет к источнику данных, определенному в ConnectionPoolDataSource
свойства объекта.
Следующий пример описывает, как системный администратор для Перерыва на кофе развернул бы a DataSource
объект, реализованный, чтобы обеспечить объединенные в пул соединения. Системный администратор обычно использовал бы инструмент развертывания, таким образом, фрагменты кода, показанные в этом разделе, являются кодом, который выполнил бы инструмент развертывания.
Чтобы получить лучшую производительность, компания Перерыва на кофе купила драйвер JDBC у DB Access, Inc., которая включает class com.dbaccess.ConnectionPoolDS
, который реализует ConnectionPoolDataSource
интерфейс. Системный администратор создает, создают экземпляр этого class, устанавливает его свойства, и регистрирует это в JNDI именование службы. Перерыв на кофе купил DataSource
class, com.applogic.PooledDataSource
, от ее поставщика сервера EJB, Application Logic, Inc. class com.applogic.PooledDataSource
объединение в пул соединения реализаций при использовании базовой поддержки, оказанной ConnectionPoolDataSource
class com.dbaccess.ConnectionPoolDS
.
ConnectionPoolDataSource
объект должен быть развернут сначала. Следующий код создает экземпляр com.dbaccess.ConnectionPoolDS
и устанавливает его свойства:
com.dbaccess.ConnectionPoolDS cpds = new com.dbaccess.ConnectionPoolDS(); cpds.setServerName("creamer"); cpds.setDatabaseName("COFFEEBREAK"); cpds.setPortNumber(9040); cpds.setDescription("Connection pooling for " + "COFFEEBREAK DBMS");
После ConnectionPoolDataSource
объект был развернут, системный администратор развертывается DataSource
объект. Следующие кодовые регистры com.dbaccess.ConnectionPoolDS
объект cpds
с JNDI именование службы. Отметьте что логическое имя, связываемое с cpds
у переменной есть подконтекст pool
добавленный под подконтекстом jdbc
, который подобен добавлению подкаталога к другому подкаталогу в иерархической файловой системе. Логическое имя любого экземпляра class com.dbaccess.ConnectionPoolDS
будет всегда начинаться jdbc/pool
. Oracle рекомендует поместить все ConnectionPoolDataSource
объекты под подконтекстом jdbc/pool
:
Context ctx = new InitialContext(); ctx.bind("jdbc/pool/fastCoffeeDB", cpds);
Затем, DataSource
class, который реализуется, чтобы взаимодействовать cpds
переменная и другие экземпляры com.dbaccess.ConnectionPoolDS
class развертывается. Следующий код создает экземпляр этого class и устанавливает его свойства. Отметьте, что только два свойства устанавливаются для этого экземпляра com.applogic.PooledDataSource
. description
свойство устанавливается, потому что оно всегда требуется. Другое свойство, которое устанавливается, dataSourceName
, дает логическое имя JNDI для cpds
, который является экземпляром com.dbaccess.ConnectionPoolDS
class. Другими словами, cpds
представляет ConnectionPoolDataSource
объект, который реализует объединение в пул соединения для DataSource
объект.
Следующий код, который был бы, вероятно, выполнен инструментом развертывания, создает a PooledDataSource
объект, устанавливает свои свойства, и связывает это с логическим именем jdbc/fastCoffeeDB
:
com.applogic.PooledDataSource ds = new com.applogic.PooledDataSource(); ds.setDescription("produces pooled connections to COFFEEBREAK"); ds.setDataSourceName("jdbc/pool/fastCoffeeDB"); Context ctx = new InitialContext(); ctx.bind("jdbc/fastCoffeeDB", ds);
В этой точке, a DataSource
объект развертывается, от которого приложение может получить объединенные в пул соединения с базой данных COFFEEBREAK
.
Пул соединения является кэшем объектов соединения с базой данных. Объекты представляют физические соединения с базой данных, которые могут использоваться приложением, чтобы соединиться с базой данных. Во время выполнения приложение запрашивает соединение от пула. Если пул содержит соединение, которое может удовлетворить запрос, он возвращает соединение с приложением. Если никакие соединения не находятся, новое соединение создается и возвращается к приложению. Приложение использует соединение, чтобы выполнить некоторую работу над базой данных и затем возвращает объект назад пулу. Соединение тогда доступно для следующего запроса соединения.
Пулы соединения способствуют повторному использованию объектов соединения и уменьшают число раз, что объекты соединения создаются. Пулы соединения значительно улучшают производительность для интенсивных базой данных приложений, потому что создание объектов соединения является дорогостоящим и с точки зрения времени и с точки зрения ресурсов.
Теперь, когда они DataSource
и ConnectionPoolDataSource
объекты развертываются, программист может использовать DataSource
объект получить объединенное в пул соединение. Код для того, чтобы получить объединенное в пул соединение точно так же как код для того, чтобы получить необъединенное в пул соединение, как показано в следующих двух строках:
ctx = new InitialContext(); ds = (DataSource)ctx.lookup("jdbc/fastCoffeeDB");
Переменная ds
представляет a DataSource
объект, который производит объединенные в пул соединения с базой данных COFFEEBREAK
. Вы должны получить это DataSource
возразите только однажды, потому что можно использовать это, чтобы произвести так много объединенных в пул соединений как необходимый. Вызов метода getConnection
на ds
переменная автоматически производит объединенное в пул соединение потому что DataSource
возразите что ds
переменная представляет, был сконфигурирован, чтобы произвести объединенные в пул соединения.
Объединение в пул соединения обычно прозрачно программисту. Есть только две вещи, которые Вы должны сделать, когда Вы используете объединенные в пул соединения:
Используйте a DataSource
возразите, а не DriverManager
class, чтобы получить соединение. В следующей строке кода, ds
a DataSource
объект, реализованный и развернутый так, чтобы это создало объединенные в пул соединения и username
и password
переменные, которые представляют учетные данные пользователя, у которого есть доступ к базе данных:
Connection con = ds.getConnection(username, password);
Используйте a finally
оператор, чтобы закрыть объединенное в пул соединение. Следующий finally
блок появился бы после try/catch
блок, который применяется к коду, в котором использовалось объединенное в пул соединение:
try { Connection con = ds.getConnection(username, password); // ... code to use the pooled // connection con } catch (Exception ex { // ... code to handle exceptions } finally { if (con != null) con.close(); }
Иначе, приложение, используя объединенное в пул соединение идентично приложению, используя регулярное соединение. Единственная другая вещь, которую мог бы заметить прикладной программист, когда объединение в пул соединения делается, состоит в том, что производительность лучше.
Следующий пример кода получает a DataSource
объект, который производит соединения с базой данных COFFEEBREAK
и использование это, чтобы обновить цену в таблице COFFEES
:
import java.sql.*; import javax.sql.*; import javax.ejb.*; import javax.naming.*; public class ConnectionPoolingBean implements SessionBean { // ... public void ejbCreate() throws CreateException { ctx = new InitialContext(); ds = (DataSource)ctx.lookup("jdbc/fastCoffeeDB"); } public void updatePrice(float price, String cofName, String username, String password) throws SQLException{ Connection con; PreparedStatement pstmt; try { con = ds.getConnection(username, password); con.setAutoCommit(false); pstmt = con.prepareStatement("UPDATE COFFEES " + "SET PRICE = ? " + "WHERE COF_NAME = ?"); pstmt.setFloat(1, price); pstmt.setString(2, cofName); pstmt.executeUpdate(); con.commit(); pstmt.close(); } finally { if (con != null) con.close(); } } private DataSource ds = null; private Context ctx = null; }
Соединение в этом примере кода участвует в объединении в пул соединения, потому что следующее является истиной:
ConnectionPoolDataSource
был развернут.DataSource
был развернут, и набор значений для dataSourceName
свойство является логическим именем, которое было связано с ранее развернутый ConnectionPoolDataSource
объект.Отметьте, что, хотя этот код очень подобен, чтобы кодировать Вас, видели прежде, это отличается следующими способами:
Это импортирует javax.sql
, javax.ejb
, и javax.naming
пакеты в дополнение к java.sql
.
DataSource
и ConnectionPoolDataSource
интерфейсы находятся в javax.sql
пакет, и конструктор JNDI InitialContext
и метод Context.lookup
часть javax.naming
пакет. Этот определенный пример кода находится в форме компонента EJB, который использует API от javax.ejb
пакет. Цель этого примера состоит в том, чтобы показать, что Вы используете объединенное в пул соединение тем же самым путем, Вы используете необъединенное в пул соединение, таким образом, Вы не должны волноваться о понимании API EJB.
Это использует a DataSource
объект получить соединение вместо того, чтобы использовать DriverManager
средство.
Это использует a finally
блок, чтобы гарантировать, что соединение закрывается.
Получение и использование объединенного в пул соединения подобны получению и использованию регулярного соединения. Когда кто-то действующий как системный администратор развернул a ConnectionPoolDataSource
объект и a DataSource
возразите должным образом, приложение использует это DataSource
объект получить объединенное в пул соединение. Приложение должно, однако, использовать a finally
блокируйте, чтобы закрыть объединенное в пул соединение. Для простоты, предыдущий пример используемый a finally
блок, но нет catch
блок. Если исключение выдается методом в try
блок, это будет брошено по умолчанию, и finally
пункт будет выполняться в любом случае.
DataSource
объекты могут быть развернуты, чтобы получить соединения, которые могут использоваться в распределенных транзакциях. Как с объединением в пул соединения, должны быть развернуты два различных экземпляра class: XADataSource
объект и a DataSource
объект, который реализуется, чтобы работать с этим.
Предположите, что сервер EJB, который купленный предприниматель Перерыва на кофе включает DataSource
class com.applogic.TransactionalDS
, который работает с XADataSource
class такой как com.dbaccess.XATransactionalDS
. Факт, что это работает с любым XADataSource
class делает сервер EJB переносимым через драйверы JDBC. Когда DataSource
и XADataSource
объекты развертываются, произведенные соединения будут в состоянии участвовать в распределенных транзакциях. В этом случае, class com.applogic.TransactionalDS
реализуется так, чтобы произведенные соединения были также объединенными в пул соединениями, которые будут обычно иметь место для DataSource
классы, обеспеченные как часть реализации сервера EJB.
XADataSource
объект должен быть развернут сначала. Следующий код создает экземпляр com.dbaccess.XATransactionalDS
и устанавливает его свойства:
com.dbaccess.XATransactionalDS xads = new com.dbaccess.XATransactionalDS(); xads.setServerName("creamer"); xads.setDatabaseName("COFFEEBREAK"); xads.setPortNumber(9040); xads.setDescription("Distributed transactions for COFFEEBREAK DBMS");
Следующие кодовые регистры com.dbaccess.XATransactionalDS
объект xads
с JNDI именование службы. Отметьте что логическое имя, связываемое с xads
имеет подконтекст xa
добавленный под jdbc
. Oracle рекомендует что логическое имя любого экземпляра class com.dbaccess.XATransactionalDS
всегда начинайте jdbc/xa
.
Context ctx = new InitialContext(); ctx.bind("jdbc/xa/distCoffeeDB", xads);
Затем, DataSource
объект, который реализуется, чтобы взаимодействовать xads
и другой XADataSource
объекты развертываются. Отметьте что DataSource
class, com.applogic.TransactionalDS
, может работать с XADataSource
class от любого поставщика драйвера JDBC. Развертывание DataSource
объект включает создание экземпляра com.applogic.TransactionalDS
class и установка его свойств. dataSourceName
свойство устанавливается в jdbc/xa/distCoffeeDB
, логическое имя, связанное с com.dbaccess.XATransactionalDS
. Это XADataSource
class, который реализует возможность распределенной транзакции DataSource
class. Следующий код развертывает экземпляр DataSource
class:
com.applogic.TransactionalDS ds = new com.applogic.TransactionalDS(); ds.setDescription("Produces distributed transaction " + "connections to COFFEEBREAK"); ds.setDataSourceName("jdbc/xa/distCoffeeDB"); Context ctx = new InitialContext(); ctx.bind("jdbc/distCoffeeDB", ds);
Теперь, когда экземпляры классов com.applogic.TransactionalDS
и com.dbaccess.XATransactionalDS
были развернуты, приложение может вызвать метод getConnection
на экземплярах TransactionalDS
class, чтобы получить соединение с COFFEEBREAK
база данных, которая может использоваться в распределенных транзакциях.
Получить соединение, которое может использоваться для распределенных транзакций, должно использовать a DataSource
объект, который был должным образом реализован и развернут, как показано в разделе, Развертывающем Распределенные транзакции. С таким DataSource
объект, вызовите метод getConnection
на этом. После того, как у Вас есть соединение, используйте его, как Вы использовали бы любое другое соединение. Поскольку jdbc/distCoffeesDB
был связан с XADataSource
объект в JNDI именование службы, следующий код производит a Connection
объект, который может использоваться в распределенных транзакциях:
Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/distCoffeesDB"); Connection con = ds.getConnection();
Есть некоторые незначительные, но важные ограничения на то, как это соединение используется, в то время как это - часть распределенной транзакции. Менеджер транзакций управляет, когда распределенная транзакция начинается и когда это фиксируется или откатывается; поэтому, код программы никогда не должен вызывать методы Connection.commit
или Connection.rollback
. Приложение никогда не должно аналогично вызывать Connection.setAutoCommit(true)
, который включает режиму автоматической фиксации, потому что это также вмешалось бы в управление менеджера транзакций границ транзакции. Это объясняет, почему новому соединению, которое создается в пределах распределенной транзакции, отключили ее режим автоматической фиксации по умолчанию. Отметьте, что эти ограничения применяются только, когда соединение участвует в распределенной транзакции; нет никаких ограничений, в то время как соединение не является частью распределенной транзакции.
Для следующего примера предположите, что заказ кофе был доставлен, который инициировал обновления к двум таблицам, которые находятся на различных серверах DBMS. Первая таблица является новым INVENTORY
таблица, и второе COFFEES
таблица. Поскольку эти таблицы находятся на различных серверах DBMS, транзакция, которая включает их обоих, будет распределенной транзакцией. Код в следующем примере, который получает соединение, обновляет COFFEES
таблица, и завершения соединение, являются второй частью распределенной транзакции.
Отметьте, что код явно не фиксирует или откатывает обновления, потому что контекстом распределенной транзакции управляет базовая системная инфраструктура сервера среднего уровня. Кроме того, предполагая, что соединение, используемое для распределенной транзакции, является объединенным в пул соединением, приложение использует a finally
блокируйте, чтобы закрыть соединение. Это гарантирует, что допустимое соединение будет закрыто, даже если исключение будет выдано, таким образом гарантируя, что соединение возвращается к пулу соединения, который будет переработан.
Следующий пример кода иллюстрирует корпоративный компонент, который является class, который реализует методы, которые может вызвать клиентский компьютер. Цель этого примера состоит в том, чтобы демонстрировать, что код программы для распределенной транзакции не отличается от другого кода за исключением того, что это не вызывает Connection
методы commit
, rollback
, или setAutoCommit(true)
. Поэтому, Вы не должны волноваться о понимании API EJB, который используется.
import java.sql.*; import javax.sql.*; import javax.ejb.*; import javax.naming.*; public class DistributedTransactionBean implements SessionBean { // ... public void ejbCreate() throws CreateException { ctx = new InitialContext(); ds = (DataSource)ctx.lookup("jdbc/distCoffeesDB"); } public void updateTotal(int incr, String cofName, String username, String password) throws SQLException { Connection con; PreparedStatement pstmt; try { con = ds.getConnection(username, password); pstmt = con.prepareStatement("UPDATE COFFEES " + "SET TOTAL = TOTAL + ? " + "WHERE COF_NAME = ?"); pstmt.setInt(1, incr); pstmt.setString(2, cofName); pstmt.executeUpdate(); stmt.close(); } finally { if (con != null) con.close(); } } private DataSource ds = null; private Context ctx = null; }