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