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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

在事务外自动保存托管JPA实体

發布時間:2023/12/3 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在事务外自动保存托管JPA实体 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring中的存儲庫和事務并存。 Spring中的所有數據庫訪問都應在事務內運行,并且通常在某個地方使用@Transactional來強制執行此操作。 但是,這并非總是必要的。 例如,當使用Spring Data時,您的存儲庫使用SimpleJPARepository來實現CRUD功能。 SimpleJPARepository使用@Transactional因此在執行CRUD操作時,已經為您處理了事務。 這可能會給人以錯誤的印象,即您不需要使用@Transactional注釋自己的類,因為僅當您知道自己在做什么時,這才是正確的。

考慮以下基于Spring Data的時間序列示例來管理汽車租賃:

public CarRentalEntry createNewRental(Car car) {CarRentalEntry latestEntry = carRentalRepository.findByCarId(car.getId());latestCarRentalEntry.setEndDate(LocalDate.now());CarRentalEntry newEntry = new CarRentalEntry();newEntry.setCarId(car.getId())newEntry.setStartDate(LocalDate.now());newEntry.setEndDate(null);carRentalRepository.save(newEntry); }

在上面的示例中,通過存儲庫獲取了特定汽車的最新租車條目,并結束了該租車條目。 然后,將創建并保存一個新的汽車租賃條目。 由于carRentalRepository是一個處理事務的SimpleJPARepository ,因此無需@Transactional carRentalRepository可以使用。 現在考慮在更改latestEntry的結束日期之前進行保存的以下latestEntry :

public CarRentalEntry createNewRental(Car car) { CarRentalEntry newEntry = new CarRentalEntry();newEntry.setCarId(car.getId())newEntry.setStartDate(LocalDate.now());newEntry.setEndDate(null);carRentalRepository.save(newEntry);CarRentalEntry latestEntry = carRentalRepository.findByCarId(car.getId());latestCarRentalEntry.setEndDate(LocalDate.now());}

從功能上講,該方法完全相同,但是在此示例中,將僅執行保存 。 因為沒有事務,對latestEntry修改將不會保存到數據庫中! 為了使這種方法有效,必須使用@Transactional注釋createNewRental() 。 如果JPA受管實體上的任何更改發生在正常JPA行為的事務內,則僅將其自動保存。 因此,問題在于為什么第一種方法不需要交易。

實際上確實如此。 當latestEntry是通過存儲庫讀取,它被加入到persistanceContext JPAS的(又名1級高速緩存) entityManager 。 當調用save()方法時,它在事務提交時刷新了persistanceContext ,這反過來又帶來了副作用,即還保留了修改后的latestEntry 。 在第二個示例中, persistanceContext latestEntry在調用save()時沒有latestEntry 。 因為在方法完成時沒有事務提交,所以不會刷新更改。 通過添加@Transactional ,再次刷新persistanceContext ,并將修改內容寫入數據庫。 請注意,第二個示例也可以通過調用carRentalRepository.flush() @Transactional ,因為它也可以在@Transactional下運行。

最重要的是,您應該控制自己的事務,因為這種情況表明容易出錯。

最后是調試Hibernate和受管實體問題時的提示。 放置斷點的良好候選類是:

  • org.springframework.orm.jpa.JpaTransactionManager
  • org.hibernate.jpa.internal.TransactionImpl.commit()要刷新的持久性上下文通常在TransactionImpl.entityManager.session.persistenceContext找到

翻譯自: https://www.javacodegeeks.com/2018/05/automatic-save-of-managed-jpa-entities-outside-of-transaction.html

總結

以上是生活随笔為你收集整理的在事务外自动保存托管JPA实体的全部內容,希望文章能夠幫你解決所遇到的問題。

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