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