我试图理解为什么saveAll在Spring Data存储库中具有比保存更好的性能。我正在使用CrudRepository
,可以看到here。
为了测试我创建并添加了10k个实体,它们只有一个id和一个随机字符串(对于基准测试我保持字符串是常量)到列表中。迭代我的列表并在每个元素上调用.save
,花了40秒。在2秒内完成对同一整个列表的.saveAll
调用。用甚至30k元素调用.saveAll
需要4秒。我确保在执行每个测试之前截断我的表。即使将.saveAll
次调用50个子列表进行批处理也需要10秒才能获得30k。
包含整个列表的简单.saveAll
似乎是最快的。
我试图浏览Spring Data源代码,但this是我发现的唯一有价值的东西。这似乎.saveAll
只是遍历整个Iterable
并在每个人身上调用.save
,就像我一样。那怎么快得多呢?它是在内部进行一些事务性批处理吗?
答案 0 :(得分:17)
在没有代码的情况下,我不得不猜测,我认为它与为save
保存的每个对象创建新事务的开销相关,而在{{1}的情况下打开一个事务}}
请注意saveAll
和save
的定义,它们都使用saveAll
注释。如果您的项目配置正确,这似乎是因为实体被保存到数据库,这意味着只要调用其中一个方法,就会创建一个事务。如果你在一个循环中调用@Transactional
,这意味着每次调用save
时都会创建一个新事务,但是在save
的情况下,有一个调用,因此创建了一个事务保存的实体数量。
我假设测试本身并不在事务中运行,如果要在事务中运行,那么所有对save的调用都将在该事务中运行,因为默认事务传播是{{1这意味着如果已经打开了一个事务,那么将在其中运行调用。如果您打算使用弹簧数据,我强烈建议您阅读transaction management in Spring。