任何人都能解释一下有什么区别:
@Resource
UserTransaction objUserTransaction;
和
EntityManager.getTransaction();
还有什么是容器管理的交易?如果我想在事务表中插入三行,我应该如何在会话外观中执行此操作。
答案 0 :(得分:27)
EJB是事务组件。事务可以由应用程序服务器本身(CMT - 容器管理的事务)管理,也可以由EJB中自己手动管理(BMT - bean管理的事务)。
EJB通过JTA规范支持分布式事务。分布式事务使用UserTransaction
进行控制,transaction annotations包含方法begin
,commit
,rollback
。
使用CMT,应用程序服务器为您启动,提交和回滚事务(根据PersistenceContextType
),并且不允许您进行干预。这意味着在这种情况下您不能访问UserTransaction
。但是,使用BMT,您可以手动执行此操作,并使用UserTransaction
自行控制事务。
我们现在转到EntityManager
。 JPA实现可以在应用程序服务器中使用,也可以单独使用。如果在独立使用,则需要使用EntityManage.getTransaction
自行划分JDBC事务。如果在应用程序服务器中使用,EntityManager
将透明地与JTA分布式事务管理器协作。
大多数情况下,您在EJB上使用带有@Required
注释的CMT。这意味着您无需同时访问UserTransaction
和EntityManager.getTransaction
。该应用程序。服务器启动并提交事务,但如果引发异常,也会小心回滚。这就是我建议你的外观。
(在EntityManager.joinTransaction
的分布式事务中,有更多细微之处,例如{{3}}或实体管理器的手动登记,但仅当您以不同方式使用这些技术作为默认值时才会这样做)。
答案 1 :(得分:8)
UserTransaction
指的是 JTA 交易实体。只有在应用程序服务器中有可用的JTA模块时才能使用它:例如,如果在Tomcat上部署应用程序(默认情况下不支持JTA),依赖于此的代码将失败。这是EJB和MDB中使用的默认事务类型。
EntityManager.getTransaction()
检索本地交易实体。这有时也称为资源本地事务。
资源本地事务与JTA事务非常不同:除其他外,资源本地事务特定于资源,而JTA事务往往特定于特定线程。
有关资源本地和JTA事务之间差异的更多信息,请参阅此stackoverflow答案:What is the difference between a JTA and a local transaction?
答案 2 :(得分:0)
除了@Marco的回答之外,它还能说明JTA和资源本地事务之间的区别。
容器管理事务[由它命名]由容器而不是您的应用程序管理。这是通过EJB层完成的,您只需编写方法,容器将围绕事务上下文包装方法,因此,如果方法的任何部分或其较低级别的调用抛出异常,则事务将回滚。
也可以使用注释进行微调。更多信息可以在https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html
找到请注意,这只能通过EJB完成,并且注入Web层的实体管理器(例如servlet或REST API)不会被容器管理,在这种情况下,您必须使用{{1来查找事务或者@Resource UserTransaction
,EntityManager.getTransaction
和begin()
自己。
从Java EE 6开始,您可以在Web层中安装EJB,因此除非您开始希望将EJB公开为Web服务,否则您不需要拥有过于复杂的项目布局。