📝오늘 공부한 것
- 실전프로젝트 - '행동대장' 트러블 슈팅
- 실전 프로젝트 - '행동대장' 유저피드백 준비
📌 트러블 슈팅
⛔ 문제점 : Dirty Checking이 작동되지 않음
마이페이지에서 이메일, 닉네임, 비밀번호 update기능을 구현하였는데 DB에 반영되지 않는 문제가 발생하였다.
[updateNickname메서드]
닉네임 변경에 대한 코드를 작성하고 dirty checking을 기대하며 Transactional을 걸어주었다.
@Transactional을 걸어주면 JPA Entity를 업데이트할 때 Dirty Checking을 지원하여 트랜잭션 안에 save를 명시적으로 호출하지 않아도 commit시에 판단해서 update를 해준다.
[Postman]
[User table]
그런데 코드를 실행하였을 때, DB에 닉네임이 정상적으로 update되지 않았다.
update메서드에 @Transactional이 동작하지 않는 것이었다!!
💯 해결
JPA 쓰기지연 기능으로 인해 update 쿼리는 영속성 컨텍스트에 저장되어 있다가 트랜잭션 commit시 한 번에 DB로 요청을 보내게 된다. 따라서 JPA의 Dirty checking을 이용하려면 변경하는 Entity가 영속성 컨텍스트 안에 있어야 한다.
그러나, 나는 User를 @AuthenticationPrincipal UserDetailsImpl클래스에서 user정보를 가져와서 사용하였다.
이로 인해, User Entity는 트랜잭션 범위 내의 영속성 컨텍스트안에 존재하지 않는다는 것이었다.
스프링컨테이너 환경에서는 영속성 컨텍스트와 트랜잭션의 생명주기가 일치하며, 각 트랜잭션은 서로 다른 Entity Manager가 관리한다. 트랜잭션 종료 후에는 영속성 컨텍스트가 소멸하기 때문에 서로 간의 정보를 공유할 수 없다.
[updateNickname메서드]
⭐ 그래서!! save매서드를 사용하여 Entity를 영속성 컨텍스트에 저장하고 DB에 반영이 가능하도록 변경하였다.
이렇게 하면 'userRepository.save(user)' 메서드를 호출하여 Entity를 영속성 컨텍스트에 저장하고, 그 후 변경작업을 수행할 수 있다.
save메서드에는 @Transactional이 적용되어 있으므로 트랜잭션 내에서 작업이 수행된다.
[SimpleJpaRepository의 save메서드]
롤백기능도 필요없기 때문에 @Transactional을 삭제하기로 하였다!!
[User table]
update메서드들에 save메서드를 추가해 주었더니 변경 성공!!
'TIL(Today I Learned)' 카테고리의 다른 글
TIL-230831(항해99 실전 프로젝트-행동대장(21)) (0) | 2023.08.31 |
---|---|
TIL-230830(항해99 실전 프로젝트-행동대장(20)) (0) | 2023.08.30 |
TIL-230828(항해99 실전 프로젝트-행동대장(18)) (0) | 2023.08.28 |
TIL-230826(항해99 실전 프로젝트-행동대장(17)) (0) | 2023.08.26 |
TIL-230825(항해99 실전 프로젝트-행동대장(16), EC2에 Swap Memory 적용) (0) | 2023.08.25 |