使用Seam POJO进行手动交易

时间:2009-11-24 11:25:42

标签: hibernate jpa transactions seam

在不使用EJB时​​将数据库事务与Seam一起使用的最佳做法是什么 - 即。何时将Seam部署为WAR?

默认情况下,Seam JavaBeans支持Transactions。我可以用@Transactional注释一个方法,这将确保需要一个事务。或者我可以使用@Transactional(NEVER)或@Transactional(MANDATORY)。我无法弄清楚如何创建自己的事务,设置超时,开始然后提交/回滚。

我尝试过使用:

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

但是如果一个事务正在进行中它会被忽略,或者如果我使用@Transactional(NEVER)注释该方法,则返回一个javax.transaction.NotSupportedException

任何帮助表示赞赏。感谢。

2 个答案:

答案 0 :(得分:8)

如您所知,交易管理是一个贯穿各领域的问题。因此,您的代码分散在模块中并不是一个好主意,因为这些问题不是他们主要关注的问题。

如果您在非EJB环境中使用JTA UserTransaction,那么JTA是可用的(Apache Tomcat不支持JTA)。

1°规则

  

所有JSF请求(Seam 2.0 +)默认启用Seam事务管理

我认为 Seam交易管理听起来更好,因为由Seam管理的交易。这意味着Seam会在幕后关注调用begin和commit。 Seam通过使用Seam Transaction Manager

扮演事务管理器的角色

1°场景:POJO + JTA可用(Apache Tomcat不支持JTA)

Seam使用的事务管理器:org.jboss.seam.transaction.UTtransaction

当JTA可用时(JBoss支持JTA),默认情况下在非EJB环境(war)中启用

如果您正在使用JPA EntityManager或Hibernate Session,则需要注册它们以允许Seam管理事务边界

请参阅9.3. Seam-managed persistence contexts如何设置Seam托管持久化上下文(使用@In注入)

然后使用@In(作用于ScopeType.CONVERSATION)注入EntityManager(EntityManager)或Session(Hibernate)

@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事务管理器通过调用joinTransaction方法

在活动的JTA UserTransaction中登记EntityManager(JPA)或Session(Hibernate)

2°情景:POJO + RESOURCE_LOCAL(Hibernate或JPA)交易

Seam使用的事务管理器(JPA):org.jboss.seam.transaction.EntityTransaction

Seam使用的事务管理器(Hibernate):org.jboss.seam.transaction.HibernateTransaction

请参阅9.3. Seam-managed persistence contexts如何设置Seam托管持久化上下文(使用@In注入)

在幕后,Seam Transaction Manager负责通过使用代理来调用底层技术的开始和提交

3°场景:EJB

Seam使用的事务管理器:org.jboss.seam.transaction.CMTTransaction

在EJB环境中默认启用。请注意,在这种情况下,Seam不会控制容器管理的事务。

的问候,

答案 1 :(得分:5)

我现在的工作方式是这样的:

//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()等