Ручные транзакции с помощью Seam POJO

Как лучше всего использовать транзакции базы данных с Seam, когда EJB не используются, т.е. при развертывании Seam как WAR?

По умолчанию Seam JavaBeans поддерживает транзакции. Я могу аннотировать метод с помощью @Transactional, и это обеспечит необходимость транзакции. Или я могу использовать @Transactional (НИКОГДА) или @Transactional (ОБЯЗАТЕЛЬНО). Что я не могу понять, так это создать свою собственную транзакцию, установить тайм-аут, начать, а затем зафиксировать / откатиться.

Я пробовал использовать:

UserTransaction utx = Transaction.instance();
utx.setTransactionTimeout(2000);
utx.begin();

Но он либо игнорируется, если транзакция уже выполняется, либо возвращает исключение javax.transaction.NotSupportedException, если я аннотирую метод с помощью @Transactional (НИКОГДА)

Любая помощь приветствуется. Спасибо.


person Damo    schedule 24.11.2009    source источник
comment
укажите полное имя @Transactional   -  person Bozho    schedule 24.11.2009
comment
org.jboss.seam.annotations.Transactional   -  person Damo    schedule 24.11.2009


Ответы (2)


Как вы знаете, управление транзакциями - это комплексная задача. Так что не рекомендуется разбросать код по модулям, где эти проблемы не являются их основной заботой.

Если вы используете JTA UserTransaction в среде, отличной от EJB, значит, JTA доступен (Apache Tomcat не поддерживает JTA).

Правило 1 °

Управление стыковочными транзакциями включено по умолчанию для всех запросов JSF (Seam 2.0+).

Я думаю, что Управление транзакциями швов лучше, чем Транзакции, управляемые швом. Это означает, что за кулисами Seam заботится о вызовах begin и commit. Seam играет роль менеджера транзакций, используя Seam Transaction Manager.

Сценарий 1 °: доступен POJO + JTA (Apache Tomcat не поддерживает JTA)

Диспетчер транзакций, используемый Seam: org.jboss.seam.transaction.UTtransaction

Включено по умолчанию в среде без EJB (война), когда доступен JTA (JBoss поддерживает JTA)

Если вы используете JPA EntityManager или Hibernate Session, вам необходимо зарегистрировать их, чтобы позволить Seam управлять границами транзакций.

См. 9.3. Контексты сохраняемости с управлением швами, как настроить контекст сохраняемости с управляемым швом (вводится с помощью @In)

Затем введите EntityManager (EntityManager) или сеанс (Hibernate) с помощью @In (с областью действия ScopeType.CONVERSATION)

@Name("businessService")
public class BusinessServiceImpl implementes BusinessService {

    @In
    private EntityManager entityManager;

    public void doSomething() {
        // You do not need to call entityManager().getTransaction().begin();
        // because Seam Transaction Manager takes care of it
        // By using proxies
        // Therefore, if you call entityManager().getTransaction().begin()
        // You will get IllegalStateException

        // Some EntityManager operations persist, find etc

        // You do not need to call entityManager().getTransaction().commit();
        // because Seam Transaction Manager takes care of it
        // By using proxies
    }

}

За кулисами диспетчер транзакций стыков подключает EntityManager (JPA) или сеанс (Hibernate) к активной пользовательской транзакции JTA, вызывая метод joinTransaction

сценарий 2 °: транзакция POJO + RESOURCE_LOCAL (в спящем режиме или JPA)

Диспетчер транзакций, используемый Seam (JPA): org.jboss.seam.transaction.EntityTransaction

Диспетчер транзакций, используемый Seam (Hibernate): org.jboss.seam.transaction.HibernateTransaction

См. 9.3. Контексты сохраняемости с управлением швами, как настроить контекст сохраняемости с управляемым швом (вводится с помощью @In)

За кулисами Seam Transaction Manager заботится о вызове begin и commit в базовой технологии с помощью прокси-серверов.

Сценарий 3 °: EJB

Диспетчер транзакций, используемый Seam: org.jboss.seam.transaction.CMTTransaction

Включено по умолчанию в среде EJB. Будьте осторожны, в этом случае Seam не контролирует транзакцию, управляемую контейнером.

С уважением,

person Arthur Ronald    schedule 10.12.2009

Сейчас я работаю так:

//don't use @Transactional annotation
public void doStuff() {
  UserTransaction userTx = (UserTransaction) org.jboss.seam.Component.getInstance("org.jboss.seam.transaction.transaction");
  userTx.setTransactionTimeout(10 * 60);  //set timeout to 60 * 10 = 600 secs = 10 mins
  userTx.begin();

  /*If entity manager is created before the transaction is started (ie. via Injection) then it must join the transaction */
  entityManager.joinTransaction();

  //do stuff    

  entityManager.persist(user);
  entityManager.flush();   //logs will show an insert at this point

  userTx.commit();   //or rollback()
}

Но если транзакция уже выполняется, и вы хотите присоединиться к ней, вы используете userTx.isActive () и т. Д.

person Damo    schedule 27.11.2009
comment
Отличный мужчина !!! Я мог бы использовать это, чтобы избежать исключения Transaction is not active. - person prageeth; 24.05.2012