Replies: 3 comments 5 replies
-
|
깔끔히 정리해주셔서 단번에 맥락을 이해했습니다~ JPA로 문제를 해결해야한다는 요구사항이 있다면, 분명 시퀀스 방식으로 변경하는 것이 맞다고 생각합니다. 그렇지만 JPA로 문제를 해결해야하는 것이 요구 사항이 아님이 떠오르네요...
뿐만 아니라 실무에서 JdbcTemplate를 성능 최적화나 JPA에서 지원하지 않는 무언가를 해결하기 위해서 종종 사용된다는 조언을 들어봤을 때, 이번 문제를 해결하는 방법으로 시퀀스도 있지만, JdbcTemplate를 활용해서 JPA 컨텍스트 없이 배치 인서트를 해결하면 어떨까 싶습니다. 물론, 이때문에 JPA 캐시측에서 바라보는 값과 데이터베이스 값이 다르면 안되므로, 애플리케이션에서 실수를 하지 않도록 주의해야겠지만요. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
|
정리하느라 고생하셨습니다 리버! 이번 기회에 identity와 sequence의 차이를 명확하게 알 수 있게 되어 좋네요~
리버의 의견대로 PK는 고유하기만 하면 되기 때문에 sequence를 적용했을 때의 단점이 크지 않아 공백 발생 문제는 크리티컬하지 않다고 생각합니다!
저는 3개 모두 sequence를 적용하거나 JdbcTemplate를 적용하거나 하나로 통일하는 것이 좋을 것 같습니다! 개인적으로는 sequence 방식으로 적용하면 batch size 설정 근거는 충분히 타당하다고 생각합니다! slot의 경우에는 time이 24 * 2, date가 7이라 50이 적절했는데, vote의 경우에는 최대 개수가 24 * 2 * 7 = 336 이라서 batch 사이즈를 조정하거나 별도로 관리해야 할 수 있을 것 같다고 생각합니다. |
Beta Was this translation helpful? Give feedback.


Uh oh!
There was an error while loading. Please reload this page.
-
1. 논의 제안 배경
현재 프로젝트에서 엔티티 ID 생성 전략으로
GenerationType.IDENTITY를 사용하고 있습니다.IDENTITY전략은 구현이 간단하지만 JPA의 배치 삽입 기능을 비활성화시킵니다.IDENTITY전략 하에서JpaRepository의saveAll(List<Entity> entities)을 호출하면, 영속성 컨텍스트가 엔티티를 관리하기 위해persist()시점에 즉시INSERT쿼리를 실행하여 DB로부터 ID를 받아와야 합니다. 결과적으로 100개의 엔티티를saveAll하면 1개의 Batch INSERT 가 아닌INSERT쿼리 100개가 실행됩니다.현재 이 문제를 해결하기 위해
available_date_slot,available_time_slot과 같이 배치 삽입이 필요한 로직에서JdbcTemplate의batchUpdate를 사용하는 별도의 Repository(JdbcSlotBatchRepository)를 구현해 사용하고 있습니다.이는 JPA와
JdbcTemplate코드가 공존하여 코드 복잡성 증가한다는 문제가 있습니다.이에
JdbcTemplate의존성을 제거하고 JPAsaveAll의 배치 삽입 기능을 활성화하기 위해 일부 엔티티의 ID 생성 전략을GenerationType.SEQUENCE로 변경하는 것을 제안합니다.2. IDENTITY vs. SEQUENCE 전략 비교
IDENTITYauto_increment기능에 전적으로 의존합니다. (ex. MySQL의AUTO_INCREMENT)INSERT쿼리 시점:persist()(저장) 호출 즉시 DB로INSERT쿼리가 실행됩니다.IDENTITY전략은INSERT를 해야만 ID를 알 수 있기 때문입니다.saveAll(100개)호출 시, 쿼리를 모으지 못하고INSERT쿼리가 100번 실행됩니다.@GeneratedValue(strategy = GenerationType.IDENTITY)하나로 간단합니다.SEQUENCESEQUENCE객체를 사용합니다.INSERT쿼리 시점:persist()시점에는INSERT가 실행되지 않습니다.allocationSize만큼의 ID를 DB 시퀀스로부터 미리 받아와 메모리 ID 풀에 보관합니다.saveAll(100개)호출 시,batch_size설정에 맞춰 Batch INSERT 1번 (혹은 몇 번)으로 실행됩니다.saveAll()동작: (시퀀스 조회 1~2번) + Batch INSERT 1번allocationSize와batch_size튜닝을 통해 성능을 극대화할 수 있습니다.allocationSize로 인해 ID 공백(Gap)이 발생할 수 있습니다. (서버 재시작 시 메모리에 있던 ID 풀이 유실됨)@SequenceGenerator설정,allocationSize설정,batch_size설정 등 상대적으로 설정이 복잡합니다.3. 적용 대상 엔티티 논의
SEQUENCE전략은 한 번의 요청으로 여러 건의 데이터 삽입이 발생하는 엔티티에 주로 적용합니다.현재 프로젝트에서 이에 해당하는 엔티티는 다음과 같습니다.
• available_date_slot (일정 생성 시 여러 날짜 슬롯 생성)
• available_time_slot (일정 생성 시 여러 시간 슬롯 생성)
• vote (사용자가 여러 슬롯에 한 번에 투표)
이 엔티티들에 대해서만
SEQUENCE전략을 도입하는 것을 제안합니다.4. 결론
JdbcTemplate을 사용하는 현재의 배치 방식 대신SEQUENCE전략을 도입해 JPA의saveAll을 통한 깔끔하고 효율적인 배치 삽입 처리가 장기적으로 옳다고 생각합니다.아래 사항에 대한 의견 부탁드립니다!
SEQUENCE전략 도입에 따른 ID 공백(Gap) 발생에 동의하는지allocationSize와batch_size는 몇으로 설정하는 것이 적절한지allocationSize와batch_size를 모두 50으로 통일하면 좋을 것 같습니다.Beta Was this translation helpful? Give feedback.
All reactions