강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

강낭콩님의 프로필 이미지
강낭콩

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

변경 감지와 병합(merge)

for문에서 변경감지 사용할 때 Exception 발생 문제

작성

·

235

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 발생 가능 지점
}
}

 

 

 

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 강낭콩님

트랜잭션은 문제가 발생했을 때 함께 원복하는 것이 원래의 목적입니다.

따라서 함께 원복되는 것이 맞습니다.

그런 목적이 아니라면 루프를 돌 때 마다 트랜잭션을 각각 실행해서 처리하셔야 합니다.

감사합니다.

강낭콩님의 프로필 이미지
강낭콩

작성한 질문수

질문하기