Как работают управляемые бином транзакции?
Я новичок как в EJB, так и в управляемых бинах транзакциях. Покинув Интернет, я обнаружил, что могу написать сессионный компонент EJ, который выполняет транзакции "управляемым компонентом", например:
@TransactionManagement(value=TransactionManagementType.BEAN)
@Stateless
public class OperationBean {
@Resource
private UserTransaction userTransaction;
public void operation() {
try{
userTransaction.begin();
Op1();
Op2();
Op3();
userTransaction.commit();
} catch(Exception e){
userTransaction.rollback();
}
}
}
Тем не менее, я не понимаю, что происходит, если Op3 выдает исключение (). Как отменяются Op1() и Op2()?
Другой вопрос, как мне связать это с JSF? Мне нужно написать форму в JSF, которая отправляет свои данные на сервер, и OperationBean выполняет 3 операции на основе полученных данных. Эти операции включают в себя операции с базой данных (3 обновления) и не имеют смысла индивидуально.
Спасибо!
1 ответ
Когда вы звоните userTransaction.begin()
Проще говоря, JTA начинает транзакцию на уровне базы данных. Теперь все изменения данных, которые вы выполняете, выполняются внутри транзакции. Если все в порядке, исполнение приходит к userTransaction.commit()
и база данных исправляет транзакцию. Если что-то идет не так, звоните userTransaction.rollback()
в блоке catch и базе данных удаляются все изменения, которые вы делаете после begin()
,
В двух словах трудно объяснить, как работают транзакции базы данных, но в основном база данных изолирует все изменения во время транзакции от других клиентов до commit()
или же rollback()
вызывается и предотвращает внешние обновления данных, с которыми вы работаете.
В JSF вы можете создать @ManagedBean
и введите свой OperationBean
в это с @EJB
аннотаций. Вы должны получить что-то вроде этого
@ManagedBean
public class Operation {
@EJB
private OperationBean operationBean;
public void doOperation() {
operationBean.operation();
}
}
и по вашему мнению
<h:form>
<h:commandButton action="#{operation.doOperation}" value="Do Operation"/>
</h:form>
Итак, вы делаете это правильно. Предполагая, что вам действительно нужны транзакции, управляемые компонентом, а не контейнером.