【问题标题】:Manual Transactions with Seam POJOSeam POJO 的手动事务
【发布时间】:2010-12-19 20:31:30
【问题描述】:

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

Seam JavaBeans 默认支持事务。我可以用 @Transactional 注释一个方法,这将确保需要一个事务。或者我可以使用@Transactional(NEVER) 或@Transactional(MANDATORY)。我不知道该怎么做是创建自己的事务,设置超时,开始然后提交/回滚。

我尝试过使用:

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

但是如果事务已经在进行中,则它要么被忽略,要么如果我用 @Transactional(NEVER) 注释该方法,则返回 javax.transaction.NotSupportedException

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

【问题讨论】:

  • 给出@Transactional 的完全限定名称
  • org.jboss.seam.annotations.Transactional

标签: hibernate jpa transactions seam


【解决方案1】:

我目前的工作方式是这样的:

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

【讨论】:

  • 好人!!!我可以使用它来避免“交易未激活”异常。
【解决方案2】:

如您所知,事务管理是一个横切关注点。因此,您的代码分散在模块中并不是一个好主意,而这些关注点不是他们的主要关注点。

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

1°规则

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

我认为 Seam 事务管理 听起来比 由 Seam 管理的事务 更好。这意味着 Seam 在幕后负责调用 begin 和 commit。 Seam 通过使用 Seam 事务管理器扮演事务管理器的角色

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

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

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

如果您使用 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 Transaction Manager 通过调用 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 使用代理在底层技术中负责调用 begin 和 commit

3°场景:EJB

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

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

问候,

【讨论】:

    猜你喜欢
    • 2012-03-24
    • 2017-09-14
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多