1. 개요

이 빠른 사용방법(예제)에서는 Spring Data의 save()saveAll() 메서드 간의 성능 차이에 대해 알아봅니다 .

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<Book, Long> {
}

3. 성능

성능을 테스트하기 위해 두 가지 방법을 모두 사용하여 10,000권의 책을 저장합니다.

먼저 save() 메서드를 사용합니다 .

for(int i = 0; i < bookCount; i++) {
    bookRepository.save(new Book("Book " + i, "Author " + i));
}

그런 다음 책 List을 만들고 saveAll() 메서드를 사용하여 한 번에 모든 을 저장합니다.

List<Book> bookList = 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. 차이점

두 메서드의 구현을 살펴보면 saveAll() 이 각 요소를 반복하고 각 반복에서 save() 메서드를 사용 한다는 것을 알 수 있습니다 . 이는 성능 차이가 그렇게 크지 않아야 함을 의미합니다.

더 자세히 살펴보면 두 메서드 모두 @Transactional 로 어노테이션 처리되어 있음을 알 수 있습니다.

또한 기본 트랜잭션 전파 유형은 REQUIRED 입니다. 즉, 제공되지 않으면 메서드가 호출될 때마다 새 트랜잭션이 생성됩니다 .

우리의 경우 save() 메소드를 호출할 때마다 새로운 트랜잭션이 생성되는 반면, saveAll() 을 호출 하면 하나의 트랜잭션만 생성되고 나중에 save() 에 의해 재사용됩니다 .

이 오버헤드는 앞서 확인한 성능 차이로 이어집니다.

마지막으로 일괄 처리가 활성화되면 트랜잭션 수준에서 수행되기 때문에 오버헤드가 더 커집니다.

5. 결론

이 기사에서는 Spring Data save()saveAll() 메소드 의 성능 차이에 대해 배웠습니다 .

궁극적으로 다른 방법보다 한 방법을 사용할지 여부를 선택하면 응용 프로그램의 성능에 큰 영향을 미칠 수 있습니다.

항상 그렇듯이 이 예제의 코드는 GitHub에서 사용할 수 있습니다 .

Persistence footer banner