在不使用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
任何帮助表示赞赏。感谢。
答案 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()等