В предыдущем посте я писал про транзакции, которые управляются контейнером EJB. Сейчас я продолжаю знакомство с транзакциями и выкладываю свои заметки про транзакции, управляемые приложением.
Транзакции, управляемые контейнером имеют одно ограничение - когда метод запускается, он может быть ассоциирован только с одной транзакцией или без транзакций вовсе. Если требуется иное, имеет смысл использовать транзакции, управляемые бином (bean-managed transactions).
Когда транзакции находятся под управлением приложения, можно использовать JDBC или JTA-транзакции.
JTA-транзакции позволяют работать с базами данных разных производителей. JTA-транзакции не поддерживают вложенных транзакций, т.е. нельзя стартовать новую транзакцию, пока не завершилась другая.
Для управления транзакциями используются следующие методы: begin, commit и rollback. В JDBC-транзакции метод begin опускается, т.к. Подразумевается, что транзакция стартовала перед началом работы с БД.
Метод stateless session бина должен завершить транзакцию до того, как вернет результат, в то время как stateful session bean может сохранять состояние транзакции между обращениями клиента к методу. Даже если клиент закрывал и заново открывал соединение с БД, транзакция будет существовать до тех пор, пока не будет вызван метод commit или rollback.
Если stateful session bean использует JDBC-транзакцию, то её состояние так же может сохраняться между вызовами пользователя за тем исключением, что если jdbc-соединение будет закрыто - транзакция оборвется.
В транзакциях, управляемых приложением нельзя запускать методы управления транзакциями уровня контейнера getRollbackOnly и setRollbackOnly интерфейса EJBContext. Вместо этого надо использовать методы getStatus и rollback интерфейса UserTransaction.
Пример JDBC-транзакции:
Таймаут транзакций под управлением EBJ-контейнера выставляется сервером приложений, а транзакций под управлением приложением - методом setTransactionTimeout интерфейса UserTransaction. По умолчанию таймаут равен нулю, что значит, что он никогда не наступит.
Транзакции, управляемые контейнером имеют одно ограничение - когда метод запускается, он может быть ассоциирован только с одной транзакцией или без транзакций вовсе. Если требуется иное, имеет смысл использовать транзакции, управляемые бином (bean-managed transactions).
Когда транзакции находятся под управлением приложения, можно использовать JDBC или JTA-транзакции.
JTA-транзакции позволяют работать с базами данных разных производителей. JTA-транзакции не поддерживают вложенных транзакций, т.е. нельзя стартовать новую транзакцию, пока не завершилась другая.
Для управления транзакциями используются следующие методы: begin, commit и rollback. В JDBC-транзакции метод begin опускается, т.к. Подразумевается, что транзакция стартовала перед началом работы с БД.
Метод stateless session бина должен завершить транзакцию до того, как вернет результат, в то время как stateful session bean может сохранять состояние транзакции между обращениями клиента к методу. Даже если клиент закрывал и заново открывал соединение с БД, транзакция будет существовать до тех пор, пока не будет вызван метод commit или rollback.
Если stateful session bean использует JDBC-транзакцию, то её состояние так же может сохраняться между вызовами пользователя за тем исключением, что если jdbc-соединение будет закрыто - транзакция оборвется.
В транзакциях, управляемых приложением нельзя запускать методы управления транзакциями уровня контейнера getRollbackOnly и setRollbackOnly интерфейса EJBContext. Вместо этого надо использовать методы getStatus и rollback интерфейса UserTransaction.
Пример JDBC-транзакции:
public void ship (String productId, String orderId, int quantity) {Пример JTA-транзакции:
try {
con.setAutoCommit(false);
updateOrderItem(productId, orderId);
updateInventory(productId, quantity);
con.commit();
} catch (Exception ex) {
try {
con.rollback();
throw new EJBException("Transaction failed:" +
ex.getMessage());
} catch (SQLException sqx) {
throw new EJBException("Rollback failed:" +
sqx.getMessage());
}
}
}
public void withdrawCash(double amount) {
UserTransaction ut = context.getUserTransaction();
try {
ut.begin();
updateChecking(amount);
machineBalance -= amount;
insertMachine(machineBalance);
ut.commit();
} catch (Exception ex) {
try {
ut.rollback();
} catch (SystemException syex) {
throw new EJBException ("Rollback failed:" + syex.getMessage());
}
throw new EJBException ("Transaction failed:" + ex.getMessage());
}
}
Таймаут транзакций под управлением EBJ-контейнера выставляется сервером приложений, а транзакций под управлением приложением - методом setTransactionTimeout интерфейса UserTransaction. По умолчанию таймаут равен нулю, что значит, что он никогда не наступит.