本文介紹了將實體批量插入數據庫(Quarkus、Hibernate)的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
首先:我不習慣Quarkus或Hibernate(我幾乎都是.Net)
問題:
我的服務收到一個大約10K的列表(我猜這是最常見的數字)。
這是通過資源終結點完成的,它需要+10秒才能完成,遠遠超過10秒。并且服務沒有響應。
*Endpoint -> Service/Business -> DAO*
@Override
public void create(FooBusiness foo) {
var statuses = new ArrayList<StatusDto>();
for(var i = 1; i < foo.getFromList().size(); i++){
var bar = foo.getFromList().get(i);
statuses.add(new StatusDto(bar.x, bar.y));
}
statusDao.create(statuses);
}
statusDao.Create()用@Transactional
注釋:
DAO為@ApplicationScoped
此EM為:
@PersistenceContext
EntityManager entityManager;
statusDao.Create():
@Transactional
public List<StatusDto> create(List<StatusDto> dto) {
for(var i = 0; i < dto.size(); i++){
var status = dto.get(i);
status.setCreatedTimestamp(LocalDateTime.now());
entityManager.persist(status);
}
entityManager.flush();
return dto;
}
我已經閱讀了很多關于這方面的帖子,其中很多都建議使用此屬性,并將Persistent循環拆分為與批處理大小相同:
quarkus.hibernate-orm.jdbc.statement-batch-size
問題是,當我將它添加到應用程序中時,我得到了這個涂色:
無法解析配置項‘Statement-Batch-Size’
我花了幾乎一天的時間試圖找到如何加快速度的解決方案,這里有什么明顯的遺漏嗎?
和/或:
我是否可以將從service
到dao
的調用包裝在某種魔法火中,并忘記Quarkus或Vert.x中內置的調用?
推薦答案
Hibernate將您持久化的所有實體保留在持久化上下文中,因此您將獲得越來越多的內存,這可能會導致較差的性能。如果您不再像看起來那樣需要這些實體,您可以分批刷新和清除它們,例如50個項目。
for (var i = 0; i < dto.size();) {
var status = dto.get(i);
status.setCreatedTimestamp(LocalDateTime.now());
entityManager.persist(status);
i++;
if ((i % 50) == 0) {
entityManager.flush();
entityManager.clear();
}
}
entityManager.flush();
這篇關于將實體批量插入數據庫(Quarkus、Hibernate)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,