[JPA] save(), saveAll(), saveAndFlush() 차이

손은실·2022년 7월 16일
0

Spring

목록 보기
7/7
post-thumbnail

1. 상황

Card 객체를 DB에 insert 하기위해 JPA 메소드를 쓰려는데 insert 쿼리 메소드가 3개나 있다. 난 뭘 써야하나?


2. 뭐가 다른걸까?

save()

  • 1개 저장
  • 즉시 DB에 저장되지 않고 영속성 컨텍스트에 저장되었다가 flush() 또는 commit() 해줘야 DB에 저장된다.

flushcommit의 차이?

  • flush
    • 영속성 컨텍스트의 변경 내용을 DB에 동기화 (비우는 것이 아님)
    • Transaction commit을 하면 flush가 동작해 쓰기 지연에 있는 쿼리들을 수행
    • rollback 가능

  • commit
    • DB에 동기화된 내용들이 영구 저장되어 rollback 불가능

saveAll()

  • n개 저장
  • List에 entity를 모두 담아서 한 번에 saveAll 하는 게 성능면에서 더 좋음

saveAndFlush()

  • 즉시 DB에 변경 사항을 적용한다.
    save 를 호출해 엔티티를 넣고, flush()를 추가적으로 해주는 것을 알 수 있다.

데이터의 개수와 목적에 따라 맞는 것을 사용하면 되겠다!


save 와 saveAll 의 성능 차이

  • save

위 코드는 save 메소드이다. entity를 1개 씩 받아 1개 씩 처리한다.

save 는 트랜잭션이 있으면 프록시 로직을 타고 기존 트랜잭션에 참여한다.
트랜잭션이 없으면 생성됐다가 종료된다.

  • saveAll

saveAll 은 여러 개의 entity를 for문을 이용해 같은 인스턴스에서 처리한다.

saveAllsave를 호출하지만 같은 인스턴스에서 내부적으로 계속 호출하니까 다음 순서의 save 가 프록시 로직을 타지 않는 것이다.
트랜잭션이 없으면 한 번 생성하고 기존의 트랜잭션에 참여해 save를 호출하기 때문에 프록시 로직을 또 타지 않는다.

결론적으로, 프록시 로직을 타느냐 타지 않느냐의 차이가 성능의 차이다.


3. 마무리

여태 제공되는 인터페이스들을 편하게 쓰기만 했는데 이번에 메소드 내부를 들여다보고서 내가 쓴 메소드가 어떻게 흘러가고, 어떻게 적용이 되는 건지 뜯어 볼 필요가 있다는 생각이 들었다.

뜯어보면 볼수록 새로운 개념들이 쏟아지지만 하나씩 검색해보고 이해하니 퍼즐이 맞춰지는 기분이다.

모양도 안 맞는 퍼즐을 힘으로 끼워 넣었다가 다 빼고 테두리부터 제대로 끼우는 느낌이랄까...ㅎ

도움 받은 글

JPA - save() 와 saveAndFlush() 의 차이
[Spring] JPA의 save와 saveAll의 성능 차이, 그리고 원인
[JPA TIL] 플러시(Flush)와 Transaction commit

0개의 댓글