1. Обзор
В этом кратком руководстве мы узнаем о разнице в производительности между методами save() и saveAll() в данных Spring.
2. Применение
Чтобы проверить производительность, нам понадобится приложение Spring с сущностью и репозиторием.
Давайте создадим сущность книги:
@Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String title; private String author; // constructors, standard getters and setters }
Кроме того, давайте создадим для него репозиторий:
public interface BookRepository extends JpaRepository{ }
3. Производительность
Чтобы проверить производительность, мы сэкономим 10 000 книг, используя оба метода.
Во-первых, мы будем использовать метод save() :
for(int i = 0; i < bookCount; i++) { bookRepository.save(new Book("Book " + i, "Author " + i)); }
Затем мы создадим список книг и используем метод сохранить все () , чтобы сохранить их все сразу:
ListbookList = new ArrayList<>(); for (int i = 0; i < bookCount; i++) { bookList.add(new Book("Book " + i, "Author " + i)); } bookRepository.saveAll(bookList);
В наших тестах мы заметили, что первый метод занял около 2 секунд, а второй-примерно 0,3 секунды.
Кроме того, когда мы включили пакетные вставки JPA, мы наблюдали снижение производительности метода save() до 10% и увеличение производительности метода saveAll() до 60%.
4. Различия
Изучая реализацию двух методов, мы видим, что save All() повторяет каждый элемент и использует метод save() в каждой итерации. Это означает, что разница в производительности не должна быть такой большой.
Присмотревшись повнимательнее, мы видим, что оба метода снабжены аннотациями @Transactional .
Кроме того, тип транзакции по умолчанию ТРЕБУЕТСЯ, что означает, что если не указано, новая транзакция создается каждый раз, когда вызываются методы .
В нашем случае каждый раз, когда мы вызываем метод save () , создается новая транзакция, в то время как при вызове saveAll () создается только одна транзакция, и она повторно используется позже save() .
Эти накладные расходы приводят к разнице в производительности, которую мы заметили ранее.
Наконец, накладные расходы увеличиваются при включении пакетной обработки из-за того, что она выполняется на уровне транзакций.
5. Заключение
В этой статье мы узнали о разнице в производительности между методами save() и saveAll() в данных Spring.
В конечном счете, выбор того, использовать ли один метод вместо другого, может оказать большое влияние на производительность приложения.
Как всегда, код для этих примеров доступен на GitHub .