2010-03-25 117 views
26

任何人能解释什么区别:是什么@Resource UserTransaction的和EntityManager.getTransaction之间的差异()

@Resource 
UserTransaction objUserTransaction; 

EntityManager.getTransaction(); 

而且也什么容器管理的事务?如果我想在事务中的表中插入三行,我应该如何在会话外观中完成它。

+1

一篇很好的文章,可以更好地了解EJB事务,IMO,必须阅读http://entjavastuff.blogspot.com/2011/02/ejb-transaction-management-going-deeper.html – thirdy 2013-03-12 06:51:12

回答

26

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。该应用程序。服务器启动并提交事务,但如果引发异常,还要小心回滚。这是我建议你的门面。

(还有更多的细微之处,如PersistenceContextTypeEntityManager.joinTransaction在分布式事务的实体管理器的手动入伍,但如果你在一个不同的方式作为默认使用的技术,这只是)。

+3

您确定当在应用服务器中运行时,EntityManager#getTransaction()与JTA分布式事务协作?我不这么认为,我的理解是它返回一个资源本地事务,它可以用来保存当前JTA事务之外的数据。 – 2010-09-01 21:59:06

+0

@Pascal EntityManager与JTA协作,所以你不应该使用'EntityManager#getTransaction'。根据javadoc,如果在JTA EntityManager上调用,则“EntityManager#getTransaction”会抛出IllegalStateException异常。 – ewernli 2010-09-02 06:07:55

+2

确实,'getTransaction'在JTA EntityManager上调用时会引发异常)。实际上,我想到的例子(来自“Pro JPA 2”)是在会话Bean中获得应用程序管理的资源本地EM - 例如,用于审计日志 - 以及资源本地事务,您可以在JTA事务之外尽可能多地开始/提交资源。但是我意识到我误解了你的答案,这与你写的不同。谢谢! – 2010-09-02 12:05:25

7

UserTransaction指的是JTA交易实体。只有在应用程序服务器中有可用的JTA模块时才能使用它:例如,如果您在Tomcat上部署应用程序(默认情况下不支持JTA),则依赖于此的代码将失败。这是EJB和MDB中使用的默认事务类型。

EntityManager.getTransaction()检索本地交易实体。这有时也被称为资源本地交易。

资源本地事务与JTA事务有很大不同:其中,资源本地事务特定于某个资源,而JTA事务往往针对特定的线程。

有关资源的本地和JTA事务之间的区别的详细信息,请参阅本计算器在这里回答:What is the difference between a JTA and a local transaction?

0

除了@马可的答案,没有很好地告诉JTA之间的区别和资源本地事务。

容器管理的事务[由于它的名称]由容器而不是您的应用程序管理。这是通过EJB层完成的,您只需编写您的方法,并且容器将围绕事务上下文封装方法,因此如果方法的任何部分或其较低级别的调用引发异常,事务将回滚。

它也可以使用注释进行微调。可以在这里找到更多的信息https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

请注意,这只能通过EJB来完成,并且在Web层上注入的实体管理器(例如servlet或REST API)不能由容器管理,在这种情况下您必须请自己使用@Resource UserTransactionEntityManager.getTransaction,begin()commit()查找交易。

从Java EE 6开始,您可以在Web层中使用EJB,因此除非您希望将EJB公开为Web服务,否则不需要有太复杂的项目布局。

+0

在EE容器管理的事务中,通过“@Transactional”注释在EJB外部可用。 – 2014-12-15 18:08:53

+0

JTA事务*不一定是CMT,因为JTA可以在Bitronix和Atomikos等库的应用程序服务器(或“容器”)之外使用。 – Marco 2015-03-12 11:34:47

相关问题