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

박성수님의 프로필 이미지
박성수

작성한 질문수

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

트랜잭션 롤백에 관한 질문

해결된 질문

작성

·

283

·

수정됨

0

tx.begin()    
Member member = new Member(); 
member.setName("start");  
em.persist(member);    
tx.commit(); 

 

안녕하세요 트랜잭션 공부를 하다가 질문이 생겨 이렇게 글 남기게 되었습니다!

 

위처럼 작성하면, Member 테이블에 잘 생성됨을 확인했는데요,

트랜잭션 롤백의 작동에 대해 이것저것 해보다가

 

tx.begin();

Member findMember = em.find(Member.class, 저장된member아이디);

try {

findMember.setName("newName");

throw new Exception();

} catch (Exception e) {

tx.rollback();

}

System.out.println(findMember.getName()); // 이 줄에서 원래의 start가 나오길 기대했으나, newName이 나옵니다

 

 

findMember 객체가 영속성 컨텍스트에 의해 관리되고 있으므로, 트랜잭션이 롤백된다면 마지막 프린트 문에서 findMember의 name 속성이 원래의 상태인 'start' 로 돌아가길 기대했는데요.

질문: 실제로 프린트를 해보니, 'start'가 아닌 'newName'으로 인식되어 이렇게 프린트되는 이유가 궁금합니다!


제가 이해하려고 시도한 것..

 

조금 이해가 안되어서 em.contains(findMember) 를 해보니, 정확히 tx.rollback() 이전에는 true, 이후에는 false로 출력이 되더라고요.

 

위의 결과로 추정해본 바로는 tx가 엔티티 객체를 직접 인식하는 것이 아니라, em안의 1차 캐시의 변경된 내역을 인식하고 있고, 엔티티 객체는 그와 별개로 자바 코드에서 활용할 수 있는 용도인가..? 라고 이해를 해봤고,

트랜잭션 롤백시, 엔티티 객체는 em과 연관없는 순수 자바 객체가 되며 때문에 객체가 있는 메모리 상의 바뀐 필드의 값이 다시 변경될 필요가 없는건가? (어짜피 트랜잭션으로 em안의 1차 캐시 변경부를 원상태로 바꿔주면 DB에는 아무런 변화가 없을 것이기 때문에) 라고 이해를 했습니다.

 

아무래도 혼자서 생각해본 이유이기에 정확하지 않을 것 같습니다.

위와 같은 질문과 제 뇌피셜인,, 이해한 바에 대해 피드백 주시면 감사하겠습니다!!

 

감사합니다!!

 

답변 1

2

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

안녕하세요. 박성수님

트랜잭션을 롤백하는 것은 데이터베이스에 있는 데이터만 롤백하는 것입니다.

객체의 데이터는 롤백하지 않습니다.

이렇게 두는 여러가지 이유가 있지만 실용적인 관점에서 예외가 발생했을 때 객체에 어떤 데이터가 들어가서 실패했는지 확인할 수 있습니다.

추가로 트랜잭션이 실패한 경우에는 해당 엔티티를 비즈니스 로직에 활용하지 않아야 합니다. 어떤 데이터를 넣었을 때 문제가 발생했는지 로그를 남기는 정도에만 사용하는 것이 좋습니다.

감사합니다.

박성수님의 프로필 이미지
박성수
질문자

상세한 답변 감사합니다!!

박성수님의 프로필 이미지
박성수

작성한 질문수

질문하기