2010-03-02 160 views
27

我在EJB3無狀態會話bean中使用CMT。另外我創建了自己的Exception,註釋「@ApplicationException(rollback = true)」。EJB3事務回滾

  1. 當我想要回滾事務時,是否必須使用「context.setRollbackOnly()」?

  2. 我可以通過在bean中的公共方法內引發異常來回滾事務嗎?

  3. 如果是這樣(的答案,Q#2是肯定的),我必須在方法聲明異常拋出異常的方法的還是會足以隨便扔在方法內部異常和處理它在同一個方法裏面呢? (我不想傳播異常到一個新的水平。我只是想回滾除外。)提前

感謝。 ;)

回答

62

首先,沒有回滾異常,它是事務的回滾。

  1. 如果您拋出異常與@ApplicationException(rollback=true),您不必手動回滾事務。 Context.setRollbackOnly()強制容器回滾事務,如果沒有異常。
  2. 檢查異常本身不回滾事務。它需要有註釋@ApplicationException(rollback=true)。如果異常是RuntimeException,並且未捕獲異常,則會強制容器回滾事務。但要小心,容器將在這種情況下放棄EJB實例。
  3. 正如2.)所述,如果您拋出一個RuntimeException,交易將自動回滾。如果您在代碼中捕獲了已檢查的異常,則必須使用setRollbackOnly來回滾事務。

如需進一步信息,請查看免費書籍Mastering EJB。它非常好地描述了回滾場景,並且可以免費下載。

+0

「如果您在代碼中捕獲了已檢查的異常,則必須使用setRollbackOnly來回滾事務。」 你也可以拋出相同的異常並回滾事務嗎? – 2010-03-03 03:36:03

+0

您可以使用throws子句拋出相同的異常,但事務不會回滾。如果您想在這種情況下回滾事務,則必須將@ApplicationException(rollback = true)添加到您的異常中。另一種方法是將檢查的異常封裝在未經檢查的異常(例如RuntimeException)中。但是這種方式並不是首選,因爲如果拋出RuntimeException,容器會放棄bean實例並創建一個新實例。 – Steve 2010-03-03 06:30:05

+1

我只是在類似的原因看這個答案,並希望指出,你鏈接到的書不再在該網站提供完整的,它是從2006年,所以它是非常過時的,可能沒有太多用於JEE5和JEE6上下文。 – BillR 2012-09-08 00:24:44

0

關於如何防止檢查異常的註釋性聲明導致拋出時的回滾被傳播到「上層」的問題尚未在這裏得到解答。

我認爲這將需要一個圍繞所討論的EJB的包裝,它吞噬了拋出的異常。 (換句話說:我認爲自定義異常必須針對方法邊界拋出(因此在方法內處理內部並沒有捕獲到&)並傳播以獲取事務效果 - 同時也會導致EJB實例的破壞。)