25 октября 2011 г.

Декларативные транзакции в Hibernate

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



Как уже было сказано выше, декларативная модель реализовывается через аннотации. Пример бина, метод которого выполняется в транзакции:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class SoftManagerBean {
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
     public void saveSomething( Something st ) {
         if( !thingInDB( st ) ) {
             saveThing( st );
         }
     }}
Ключевыми моментами тут являются аннотации @TransactionManagement и @TransactionAttribute. Первая говорит что мы отдаем менеджмент транзакций на совесть контейнера, а вторая - что данный метод будет выполняться в транзакции. Аттрибутом аннотации могут быть: REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED и NEVER. Вот в чем различие между ними:
<имя>:
<наличие транзакции> <описание>

REQUIRED:
- Контейнер создает новую транзакцию
+ Метод присоединяется к транзакции вызвавшего

REQUIRES_NEW:
-Контейнер создает новую транзакцию
+Контейнер создает новую транзакцию и приостанавливает транзакцию вызвавшего

SUPPORTS:
- Транзакция не используется
+ Метод присоединяется к транзакции вызвавшего

MANDATORY:
- Вызывается исключение javax.ejb.EJBTransactionRequiredException
+Метод присоединяется к транзакции

NOT_SUPPORTED:
- Транзакция не используется
+Транзакция вызывающего приостанавливается и метод вызывается без транзакции

NEVER:
- Транзакция не используется
+ Вызывается исключение javax.ejb.EJBException

Rollback
Если в процессе выполнения логики приложения что-то пошло не так, то транзакцию можно отменить вызвав context.setRollbackOnly(). Данный атрибут можно выставить, если используется тип транзакции REQUIRED, REQUIRES_NEW или MANDATORY. В противном случае будет вызвано исключение IllegalStateException.

Настройка hibernate.cfg.xml
И последний шаг чтобы всё завелось - настройка конфиг файла. Пропишите следующие строчки:
jta
org.hibernate.transaction.CMTTransactionFactory
org.hibernate.transaction.JBossTransactionManagerLookup
Конечно, transaction.manager_lookup_class будет зависеть от контейнера, который вы используете. Данный случай справледлив только для jBoss. Если вы используете другой сервер приложений - обратитесь к его документации (или просто к гуглу).

3 комментария:

Примечание. Отправлять комментарии могут только участники этого блога.