任何人能解释什么区别:是什么@Resource UserTransaction的和EntityManager.getTransaction之间的差异()
@Resource
UserTransaction objUserTransaction;
和
EntityManager.getTransaction();
而且也什么容器管理的事务?如果我想在事务中的表中插入三行,我应该如何在会话外观中完成它。
任何人能解释什么区别:是什么@Resource UserTransaction的和EntityManager.getTransaction之间的差异()
@Resource
UserTransaction objUserTransaction;
和
EntityManager.getTransaction();
而且也什么容器管理的事务?如果我想在事务中的表中插入三行,我应该如何在会话外观中完成它。
EJB是事务性组件。事务可以由应用程序服务器本身(CMT - 容器管理的事务)管理,也可以由EJB(BMT - bean管理的事务)自己手动管理。
EJB支持通过JTA规范的分布式事务。分布式交易使用UserTransaction
来控制,其具有方法begin
,commit
,rollback
。
使用CMT,应用程序服务器将为您启动,提交和回滚事务(根据transaction annotations),并且不允许您干涉。这意味着在这种情况下您不能访问UserTransaction
。但是,通过BMT,您可以手动执行此操作,并使用UserTransaction
自行控制交易。我们现在来看看EntityManager
。 JPA实现既可以在应用程序服务器中使用,也可以独立使用。如果在独立模式下使用,则需要使用自己划分JDBC事务。如果在应用程序服务器内使用,则EntityManager
将透明地与JTA分布式事务管理器合作。
大多数情况下,您在EJB上使用CMT和@Required
批注。这意味着您既不需要访问UserTransaction
也不需要访问EntityManager.getTransaction
。该应用程序。服务器启动并提交事务,但如果引发异常,还要小心回滚。这是我建议你的门面。
(还有更多的细微之处,如PersistenceContextType
或EntityManager.joinTransaction
在分布式事务的实体管理器的手动入伍,但如果你在一个不同的方式作为默认使用的技术,这只是)。
您确定当在应用服务器中运行时,EntityManager#getTransaction()与JTA分布式事务协作?我不这么认为,我的理解是它返回一个资源本地事务,它可以用来保存当前JTA事务之外的数据。 – 2010-09-01 21:59:06
@Pascal EntityManager与JTA协作,所以你不应该使用'EntityManager#getTransaction'。根据javadoc,如果在JTA EntityManager上调用,则“EntityManager#getTransaction”会抛出IllegalStateException异常。 – ewernli 2010-09-02 06:07:55
确实,'getTransaction'在JTA EntityManager上调用时会引发异常)。实际上,我想到的例子(来自“Pro JPA 2”)是在会话Bean中获得应用程序管理的资源本地EM - 例如,用于审计日志 - 以及资源本地事务,您可以在JTA事务之外尽可能多地开始/提交资源。但是我意识到我误解了你的答案,这与你写的不同。谢谢! – 2010-09-02 12:05:25
UserTransaction
指的是JTA交易实体。只有在应用程序服务器中有可用的JTA模块时才能使用它:例如,如果您在Tomcat上部署应用程序(默认情况下不支持JTA),则依赖于此的代码将失败。这是EJB和MDB中使用的默认事务类型。
EntityManager.getTransaction()
检索本地交易实体。这有时也被称为资源本地交易。
资源本地事务与JTA事务有很大不同:其中,资源本地事务特定于某个资源,而JTA事务往往针对特定的线程。
有关资源的本地和JTA事务之间的区别的详细信息,请参阅本计算器在这里回答:What is the difference between a JTA and a local transaction?
除了@马可的答案,没有很好地告诉JTA之间的区别和资源本地事务。
容器管理的事务[由于它的名称]由容器而不是您的应用程序管理。这是通过EJB层完成的,您只需编写您的方法,并且容器将围绕事务上下文封装方法,因此如果方法的任何部分或其较低级别的调用引发异常,事务将回滚。
它也可以使用注释进行微调。可以在这里找到更多的信息https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html
请注意,这只能通过EJB来完成,并且在Web层上注入的实体管理器(例如servlet或REST API)不能由容器管理,在这种情况下您必须请自己使用@Resource UserTransaction
或EntityManager.getTransaction
,begin()
和commit()
查找交易。
从Java EE 6开始,您可以在Web层中使用EJB,因此除非您希望将EJB公开为Web服务,否则不需要有太复杂的项目布局。
在EE容器管理的事务中,通过“@Transactional”注释在EJB外部可用。 – 2014-12-15 18:08:53
JTA事务*不一定是CMT,因为JTA可以在Bitronix和Atomikos等库的应用程序服务器(或“容器”)之外使用。 – Marco 2015-03-12 11:34:47
一篇很好的文章,可以更好地了解EJB事务,IMO,必须阅读http://entjavastuff.blogspot.com/2011/02/ejb-transaction-management-going-deeper.html – thirdy 2013-03-12 06:51:12