Card 객체를 DB에 insert 하기위해 JPA 메소드를 쓰려는데 insert 쿼리 메소드가 3개나 있다. 난 뭘 써야하나?
save()
flush()
또는 commit()
해줘야 DB에 저장된다.
flush
와commit
의 차이?
- flush
- 영속성 컨텍스트의 변경 내용을 DB에 동기화 (비우는 것이 아님)
- Transaction commit을 하면 flush가 동작해 쓰기 지연에 있는 쿼리들을 수행
- rollback 가능
- commit
- DB에 동기화된 내용들이 영구 저장되어 rollback 불가능
saveAll()
saveAndFlush()
save
를 호출해 엔티티를 넣고, flush()
를 추가적으로 해주는 것을 알 수 있다.데이터의 개수와 목적에 따라 맞는 것을 사용하면 되겠다!
save
위 코드는 save 메소드이다. entity를 1개 씩 받아 1개 씩 처리한다.
save
는 트랜잭션이 있으면 프록시 로직을 타고 기존 트랜잭션에 참여한다.
트랜잭션이 없으면 생성됐다가 종료된다.
saveAll
saveAll
은 여러 개의 entity를 for문을 이용해 같은 인스턴스에서 처리한다.
saveAll
도 save
를 호출하지만 같은 인스턴스에서 내부적으로 계속 호출하니까 다음 순서의 save
가 프록시 로직을 타지 않는 것이다.
트랜잭션이 없으면 한 번 생성하고 기존의 트랜잭션에 참여해 save를 호출하기 때문에 프록시 로직을 또 타지 않는다.
결론적으로, 프록시 로직을 타느냐 타지 않느냐의 차이가 성능의 차이다.
여태 제공되는 인터페이스들을 편하게 쓰기만 했는데 이번에 메소드 내부를 들여다보고서 내가 쓴 메소드가 어떻게 흘러가고, 어떻게 적용이 되는 건지 뜯어 볼 필요가 있다는 생각이 들었다.
뜯어보면 볼수록 새로운 개념들이 쏟아지지만 하나씩 검색해보고 이해하니 퍼즐이 맞춰지는 기분이다.
모양도 안 맞는 퍼즐을 힘으로 끼워 넣었다가 다 빼고 테두리부터 제대로 끼우는 느낌이랄까...ㅎ
JPA - save() 와 saveAndFlush() 의 차이
[Spring] JPA의 save와 saveAll의 성능 차이, 그리고 원인
[JPA TIL] 플러시(Flush)와 Transaction commit