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