2010-03-25 112 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

相關問題