Ръчни транзакции със 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° правило

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

Мисля, че Управление на транзакциите на Seam звучи по-добре като Транзакции, управлявани от Seam. Това означава, че Seam се грижи, зад кулисите, за извикването на start и commit. Seam играе ролята на мениджър на транзакции, като използва мениджър на транзакции на Seam

1° сценарий: наличен POJO + JTA (Apache Tomcat не поддържа JTA)

Мениджър на транзакции, използван от Seam: org.jboss.seam.transaction.UTtransaction

Активирано по подразбиране в не-EJB среда (война), когато JTA е наличен (JBoss поддържа JTA)

Ако използвате JPA EntityManager или Hibernate Session, трябва да ги регистрирате, за да позволите на Seam да управлява границите на транзакциите

Вижте 9.3. Контексти на устойчивост, управлявани от Seam как да настроите контекст на устойчивост, управляван от Seam (Инжектиран чрез използване на @In)

След това инжектирайте EntityManager (EntityManager) или Session (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
    }

}

Зад кулисите, Seam Transaction Manager включва EntityManager (JPA) или Session (Hibernate) в активната JTA UserTransaction, като извика joinTransaction метод

2° сценарий: POJO + RESOURCE_LOCAL (или Hibernate, или JPA) транзакция

Мениджър на транзакции, използван от Seam (JPA): org.jboss.seam.transaction.EntityTransaction

Мениджър на транзакции, използван от Seam (Hibernate): org.jboss.seam.transaction.HibernateTransaction

Вижте 9.3. Контексти на устойчивост, управлявани от Seam как да настроите контекст на устойчивост, управляван от Seam (Инжектиран чрез използване на @In)

Зад кулисите, Seam Transaction Manager се грижи за извикването на начало и ангажиране в основната технология чрез използване на проксита

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
Страхотен човек!!! Бих могъл да използвам това, за да избегна изключение Транзакцията не е активна. - person prageeth; 24.05.2012