성능을 고려한 연관관계 매핑 & 최적화 적용
@OneToMany 컬렉션을 List에서 Set로 변경
Set은 중복 방지와 equals/hashCode 기반 비교로 인해
데이터 정합성을 강화하고, 불필요한 중복 쿼리를 줄일 수 있음
반면, 순서가 중요한 경우는 List 유지 권장
부모 엔티티와 연관된 자식이 더 이상 참조되지 않을 때 자동 삭제
데이터 정합성을 유지하기 위해 필요할 경우에만 사용
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private Set memberPrefers = new HashSet<>();
💡 예시:
회원이 탈퇴할 때, 회원의 선호 음식(MemberPrefer)도 함께 삭제됨
⚙️ 2️⃣ 트랜잭션 & 동시성 이슈 처리
🔸 트랜잭션 내 다중 엔티티 처리
하나의 트랜잭션으로 여러 엔티티를 일괄 처리
예시: 회원 탈퇴 시, 관련된 모든 데이터(MemberFood, MemberTerm, Review 등) 삭제
@Transactional
public void deleteMember(Long memberId) {
memberFoodRepository.deleteByMemberId(memberId);
memberTermRepository.deleteByMemberId(memberId);
reviewRepository.deleteByMemberId(memberId);
memberRepository.deleteById(memberId);
}
대량 삭제 시 @Modifying 과 @Query를 사용하여 Batch Delete 쿼리 최적화 가능
🔸 동시성 문제 및 락킹 전략
같은 회원이 동시에 동일한 Store를 찜할 때 중복 데이터 발생 방지
JPA의 @Lock 어노테이션으로 비관적 락(PESSIMISTIC_LOCK) 또는 낙관적 락(OPTIMISTIC_LOCK) 적용 가능
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select s from Store s where s.id = :id")
Optional<Store> findByIdForUpdate(@Param("id") Long id);
전략 | 설명 | 사용 시점 |
---|---|---|
Optimistic Lock | 버전 필드(@Version ) 기반, 충돌 시 예외 발생 | 동시성 낮을 때 |
Pessimistic Lock | DB 수준에서 행을 잠금 | 동시성 높거나 정합성 중요할 때 |