인프런 커뮤니티 질문&답변
for문에서 변경감지 사용할 때 Exception 발생 문제
작성
·
239
0
안녕하세요~ 현재 프로젝트를 진행하면서 롤백 문제를 만나게 되었는데, 제목처럼 한 트랜잭션 메소드 내에서 엔티티 List를 쿼리한 후 for 루프를 돌며 각 엔티티들의 상태값을 변경하는 로직 중에서 하나의 엔티티에서 Exception이 발생하면 모든 엔티티들에 대한 변경이 모두 롤백되어버리는 상황이 생겼습니다.
이 문제를 해결하고자 자식 트랜잭션에 전파속성을 NESTED로 주어보았는데 JPA에서는 지원하지 않는 듯 하고(NestedTransactionException 발생), 원래의 전체 엔티티를 조회해온 후 for 루프를 도는 방식에서, 단 건 엔티티를 쿼리한 후 하나의 회원 정보만 업데이트 하는 방식으로 문제를 해결하긴 하였지만, 쿼리가 처리해야할 엔티티 갯수만큼 추가적으로 발생하는 또 다른 문제가 생겨서 고민고민하다가 질문을 남겼습니다.
다른 좋은 해결 방법이 있을까요?? 문제 해결을 위한 방향을 알고 싶습니다!
아래는 대략적으로 재현한 예시 코드입니다.
@Service
class MemberService(
private val memberRepository: MemberRepository,
private val memberShipService: MemberShipService
) {
@Transactional
fun updateMemberShips() {
getAllMembers().forEach {
memberShipService.updateMemberShip(member)
}
}
}
@Service
class MemberShipService(
private val externalClient: ExternalClient // 외부 API를 콜하는 인터페이스
) {
fun updateMemberShip(member: Member) {
member.updateMemberShip()
externalClient.sendEmail() // Exception 발생 가능 지점
}
}
퀴즈
회원 가입 시 화면 입력 데이터를 엔티티 객체 대신 별도의 Form 객체로 받는 주된 이유는 무엇일까요?
데이터베이스 성능을 최적화하기 위해서
화면 종속적인 데이터나 유효성 검증 로직을 분리하기 위해서
JPA 영속성 컨텍스트와 직접적인 관계를 맺기 위해서
코드의 자동 생성 기능을 활용하기 위해서
답변 1
0
안녕하세요. 강낭콩님
트랜잭션은 문제가 발생했을 때 함께 원복하는 것이 원래의 목적입니다.
따라서 함께 원복되는 것이 맞습니다.
그런 목적이 아니라면 루프를 돌 때 마다 트랜잭션을 각각 실행해서 처리하셔야 합니다.
감사합니다.





