我最近制作了一个应用程序,该应用程序从一个数据库(旧版)中获取数据,然后将其放入另一个数据库(新的开发数据库)中。我发现困惑的是save
并不总是有效,而saveAndFlush
却可以。 legacy
数据库在一个事务select
中,而新数据库在另一个deleteAll
和save
中。
应用saveAndFlush
的运行非常慢,可以理解,但是save
并没有更好。然后,我决定使用saveAll
,但是为每个表创建一个巨大列表的想法对我来说并不成立。所以我试图像这样调用车库收集:
productRepository.saveAll(productList);
productList.clear();
productList = null;
System.gc();
然后我将jdbc.batch_size
添加到application.properties
logging.level.org.hibernate.SQL=info
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.generate-ddl = true
spring.jpa.properties.hibernate.jdbc.batch_size = 20
spring.jpa.properties.hibernate.order_inserts = true
spring.jpa.properties.hibernate.order_updates = true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data = true
之前需要花两个小时才能运行的时间现在是5分钟-巨大的性能提升。
现在我很困惑发生了什么。我读到的是“定期更新和关闭会话”。但是delete
和saveAll
是一笔交易-因此对我来说没有意义。
所以要清楚为什么是两个问题:
1)为什么save
不能总是起作用,而saveAndFlush
却可以起作用?
2)有50个表,每个表有20,000行,每个表创建一个列表,然后saveAll
,清除该列表并建议进行垃圾回收。与方法application.properties
相比,将以上内容添加到#1
可以产生非常快的应用程序。为什么?冬眠在做什么?是否定期更新和清除会话?
我认为正在发生的事情是第一层缓存保存了删除和插入操作,然后提交并希望将其刷新。显然我是错误的,或者至少不是完全正确的。