강의

멘토링

로드맵

Inflearn brand logo image

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

0__th님의 프로필 이미지
0__th

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

수업 자료

트랜잭션 내에서 엔티티를 저장하는 경우. (+ Unique 제약 조건)

작성

·

112

·

수정됨

1


1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
안녕하세요! 현재 JPA 강의를 수강하고, 프로젝트를 진행중인데 의문점이 들어서 질문 드립니다.

 

상황은 다음과 같습니다!

public UserService {
    
  @Transactional
  public void loginExample(String phoneNumber) {
  // 저장
  Member member = memberRepository.save(Member.from(phoneNumber));

  // JWT Logic.
  //
  // 
  return;

  }
}

코드가 위와 같을때, Member Entity의 id 생성 전략이 IDENTITY 인 경우, save 호출 시점에 DB에 조회를 발생시켜 아이디를 가져오는 것으로 이해하였습니다.

 

만약 동일한 핸드폰번호로 동시에 요청이 들어오게 된다면,

(핸드폰 번호는 Unique 제약 조건을 갖고 있습니다.)

특정 트랜잭션 A에서 save 까지만 성공한 후, 컨텍스트 스위칭이 발생하여 트랜잭션 B에서 save 함수를 새로 호출하게 되는 시점에 트랜잭션 A가 아직 Commit 되지 않았는데 어떻게 충돌을 감지할 수 있는지 궁금합니다!

* save 이후에 예외를 반환해도 Rollback이 되지 않고, 그대로 Row가 남아있는걸로 보아선, JPARepository.save 메서드는 부모 트랜잭션과 별개의 트랜잭션으로 동작하는 것일까요?

 

따라서, ID의 GenerationType 이 AUTO(IDENTITY)인 경우에 save 메서드는 부모 트랜잭션에 종속되지 않은 독립된 트랜잭션인 것인지가 궁금합니다..!

답변 3

2

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

안녕하세요. 0__th님

이 부분은 DB 구현에 따라 다를 것 같은데요.

Unique 제약조건은 트랜잭션과 관계없이 즉시 검사될 수 있습니다.

예를 들어서 H2 데이터베이스의 경우 Unique 제약조건에 대해서 락을 잡아둡니다.

따라서 트랜잭션과 무관하게 같은 유니크 값이 등록된다면 예외가 발생하게 됩니다.

감사합니다.

0__th님의 프로필 이미지
0__th
질문자

답변 감사합니다!!

0

0__th님의 프로필 이미지
0__th
질문자

`추가로, JPA의 save 메서드는 일반적으로 영속성 컨텍스트에 엔티티를 저장하고, 트랜잭션이 커밋되는 시점에 변경사항을 데이터베이스에 반영`

위의 코드에서 save 함수 이후에 로그를 찍어도 호출이 되지 않고 있습니다. 즉, save 메서드 호출 시점에 DB에 쿼리를 전송하고 있다는 것으로 이해하였습니다!

 

따라서, ID의 GenerationType 이 AUTO(IDENTITY)인 경우에 save 메서드는 부모 트랜잭션에 종속되지 않은 독립된 트랜잭션인 것인지가 궁금합니다..!

0

안녕하세요, 인프런 AI 인턴입니다.

질문 주신 내용을 보면, JPA를 이용한 트랜잭션 관리 및 IDENTITY 전략, 그리고 Unique 제약 조건에 따른 동시성 문제에 대한 이해를 돕고자 하는 것 같습니다.

우선, JPA에서 IDENTITY 전략을 사용할 경우, 엔티티를 저장할 때 즉시 데이터베이스에 INSERT 쿼리가 실행됩니다. 이는 IDENTITY 전략이 데이터베이스에서 식별자를 생성하기 때문입니다.

동시성 문제의 경우, 두 개의 트랜잭션이 동일한 핸드폰 번호로 저장 요청을 할 때, 실행 환경에 따라 Race Condition이 발생할 수 있습니다. 첫 번째 트랜잭션이 커밋되기 전에 두 번째 트랜잭션이 동일한 행을 삽입하려고 할 때 데이터베이스의 Unique 제약 조건 위반이 발생합니다. 이러한 문제는 일반적으로 데이터베이스에서 트랜잭션 레벨의 격리성을 통해 해결됩니다.

Transactional 어노테이션에 관해 설명드리자면, @Transactional은 메서드 단위로 트랜잭션 처리를 합니다. 따라서 save 메서드가 부모 트랜잭션과 별개의 트랜잭션으로 동작하기보다는, 메서드에서 발생하는 예외가 트랜잭션의 커밋을 막고 롤백을 유도하는 역할을 합니다.

추가로, JPA의 save 메서드는 일반적으로 영속성 컨텍스트에 엔티티를 저장하고, 트랜잭션이 커밋되는 시점에 변경사항을 데이터베이스에 반영합니다. 그래서 트랜잭션이 실패하면 롤백됩니다. 트랜잭션 내에서 예외가 발생할 시 제대로 롤백되지 않는다면, 트랜잭션 전파 설정이나 예외 처리를 확인하는 것이 필요합니다.

유사한 질문에 대한 기존 답변이 있어 참고하시면 좋을 것 같습니다:

질문자님의 상황에 맞는 해결책을 찾으셨길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0__th님의 프로필 이미지
0__th

작성한 질문수

질문하기