不使用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
任何帮助表示赞赏。谢谢。
如您所知,事务管理是一个跨领域的问题。因此,将代码分散在不是主要关注点的模块中并不是一个好主意。
如果在非EJB环境中使用JTA UserTransaction,则可以使用JTA(Apache Tomcat不支持JTA)。
1°法则
默认情况下 ,所有JSF请求(Seam 2.0+)都 启用 Seam事务管理。
我认为 Seam事务管理 听起来比 Seam管理的 事务 更好。这意味着Seam会在后台谨慎地调用begin和commit。Seam通过使用Seam事务管理器扮演事务管理器的角色
1°场景 :可用POJO + JTA(Apache Tomcat不支持JTA)
Seam使用的事务管理器:org.jboss.seam.transaction.UTtransaction
当JTA可用时,在非EJB环境(战争)中默认启用(JBoss支持JTA)
如果您使用的是JPA EntityManager或Hibernate Session,则需要注册它们以允许Seam管理事务边界
参见9.3。Seam管理的持久性上下文如何设置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
在后台,Seam Transaction Manager通过使用代理来处理调用begin和commit的底层技术
3°场景 :EJB
Seam使用的事务管理器:org.jboss.seam.transaction.CMTTransaction
在EJB环境中默认启用。请注意,在这种情况下,Seam不控制容器管理的事务。
问候,