日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jpa 异常捕获_JPA和CMT –为什么捕获持久性异常不够?

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jpa 异常捕获_JPA和CMT –为什么捕获持久性异常不够? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jpa 異常捕獲

使用CMT( 容器管理的事務 )進入EJB和JPA的世界非常舒適。 只需定義一些注釋來劃分事務邊界(或使用默認值)即可,僅此而已–無需擺弄手動開始,提交或回滾操作。 回滾事務的一種方法是從EJB的業務方法中引發非應用程序異常(或具有rollback = true的應用程序異常)。 看起來很簡單:如果在某些操作過程中可能會引發異常,并且您不想回滾tx,那么您應該捕獲該異常就可以了。 現在,您可以在同一仍處于活動狀態的事務中再次重試該易失性操作。

現在,對于從用戶組件拋出的應用程序異常,這一切都是正確的 。 問題是– 除了其他組件引發的異常之外,還有什么? 就像JPA的EntityManager拋出PersistenceException ? 這就是故事的開始。

我們想要實現的目標

設想以下情形:您有一個名為E的實體。它包含:

  • id –這是主鍵,
  • 名稱 -這是一些易于理解的實體名稱,
  • 內容 –包含字符串的任意字段–它模擬“高級屬性”,例如,在持久性/合并期間進行計算會導致錯誤。
  • 代碼 –包含OK或ERROR字符串–定義高級屬性是否成功持久保存,

您要持久化E。您假定E的基本屬性將始終被成功持久化。 但是,高級屬性需要一些額外的計算或操作,這可能會導致例如從數據庫引發約束沖突。 如果發生這種情況,您仍然希望E保留在數據庫中(但僅填充基本屬性,并且將代碼屬性設置為“ ERROR”)。

換句話說,這是您可能想到的:

  • 堅持E的基本屬性,
  • 嘗試使用脆弱的高級屬性對其進行更新,
  • 如果從步驟2拋出了PersistenceException捕獲它,將'code'屬性設置為“ ERROR”并清除所有高級屬性(它們導致異常),
  • 更新E。
  • 天真的解決方案

    轉到EJB的代碼,這就是您可以嘗試執行的方式(假設使用默認的TransactionAttributes):

    public void mergeEntity() {MyEntity entity = new MyEntity('entityName', 'OK', 'DEFAULT');em.persist(entity);// This will raise DB constraint violationentity.setContent('tooLongContentValue');// We don't need em.merge(entity) - our entity is in managed mode.try {em.flush(); // Force the flushing to occur now, not during method commit.} catch (PersistenceException e) { // Clear the properties to be able to persist the entity.entity.setContent('');entity.setCode('ERROR');// We don't need em.merge(entity) - our entity is in managed mode.} }

    這個例子有什么問題?

    捕獲由EntityManager拋出的PersistenceException 不會阻止事務回滾 。 并不是在EJB中不緩存異常將tx標記為回滾。 這是EntityManager 拋出的非應用程序異常 ,將tx標記為回滾。 更不用說資源本身可能會在內部將tx標記為回滾。 這實際上意味著您的應用程序實際上無法控制此類tx行為。 此外,由于事務回滾,我們的實體已移至分離狀態。 因此,在此方法末尾需要一些em.merge(entity) 。

    工作方案

    那么如何處理這種自動事務回滾? 因為我們正在使用CMT,所以唯一的方法是定義另一種業務方法,該方法將啟動新事務并在那里執行所有易碎的操作 。 這樣,即使將拋出(并捕獲) PersistenceException ,它也將僅標記要回滾的新事務。 我們的主要TX將保持不變。 在下面,您可以從此處看到一些代碼示例(為簡潔起見,刪除了日志記錄語句):

    public void mergeEntity() {MyEntity entity = new MyEntity('entityName', 'OK', 'DEFAULT');em.persist(entity);try {self.tryMergingEntity(entity);} catch (UpdateException ex) {entity.setContent('');entity.setCode('ERROR');} }@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void tryMergingEntity(final MyEntity entity) throws UpdateException {entity.setContent('tooLongContentValue');em.merge(entity);try {em.flush();} catch (PersistenceException e) {throw new UpdateException();} }

    注意:

    • UpdateException是@ApplicationException ,它擴展了Exception(因此默認情況下為rollback=false )。 用于通知更新操作失敗。 或者,您可以更改tryMergingEntity(-)方法簽名以返回布爾值而不是void。 此布爾值可以描述更新是否成功。
    • self是對我們自己的EJB的自我引用。 這是使用EJB容器代理的必需步驟,該代理使被調用方法的@TransactionAttribute起作用。 或者,您可以使用SessionContext#getBusinessObject(clazz).tryMergingEntity(entity) 。
    • em.merge(entity)是至關重要的。 我們正在tryMergingEntity(-)中開始新事務,因此該實體不在持久性上下文中。
    • 此方法不需要任何其他合并或刷新。 tx尚未回滾,因此批準了CMT的常規功能,這意味著在tx提交期間將自動刷新對實體的所有更改。

    讓我們再次強調最重要的一點: 如果您捕獲到異常,并不表示您當前的事務沒有被標記為回滾。 PersistenceException不是ApplicationException,即使您是否捕獲它,也將使您的tx回滾。

    JTA BMT解決方案

    我們一直在談論CMT。 JTA BMT呢? 好吧,作為一個好處,找到下面的代碼,該代碼顯示如何使用BMT處理此問題(也可在此處訪問):

    public void mergeEntity() throws Exception {utx.begin();MyEntity entity = new MyEntity('entityName', 'OK', 'DEFAULT');em.persist(entity);utx.commit();utx.begin();entity.setContent('tooLongContentValue');em.merge(entity);try {em.flush();} catch (PersistenceException e) {utx.rollback();utx.begin();entity.setContent('');entity.setCode('ERROR');em.merge(entity);utx.commit();} }

    使用JTA BMT,我們可以用一種方法來完成所有這一切。 這是因為我們控制著tx何時開始以及提交/回滾 (看看那些utx.begin()/ commit()/ rollback()。盡管如此,結果還是一樣的–拋出PersistenceException我們的tx被標記為回滾然后您可以使用UserTransaction#getStatus()進行檢查,并將其與諸如Status.STATUS_MARKED_ROLLBACK之類的常量進行比較,并可以在我的GitHub帳戶上檢查整個代碼。

    參考: JPA和CMT –為什么捕獲持久性異常不足? 從我們的JCG合作伙伴 Piotr Nowicki在Piotr Nowicki的首頁博客中獲得。

    翻譯自: https://www.javacodegeeks.com/2013/03/jpa-and-cmt-why-catching-persistence-exception-is-not-enough.html

    jpa 異常捕獲

    總結

    以上是生活随笔為你收集整理的jpa 异常捕获_JPA和CMT –为什么捕获持久性异常不够?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。