트랜잭션과 더티체킹 그리고 영속성컨텍스트에 대한 내용이다
package org.example.expert.domain.user.service;
import lombok.RequiredArgsConstructor;
import org.example.expert.domain.common.exception.InvalidRequestException;
import org.example.expert.domain.user.dto.request.UserRoleChangeRequest;
import org.example.expert.domain.user.entity.User;
import org.example.expert.domain.user.enums.UserRole;
import org.example.expert.domain.user.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class UserAdminService {
private final UserRepository userRepository;
@Transactional
public void changeUserRole(long userId, UserRoleChangeRequest userRoleChangeRequest) {
User user = userRepository.findById(userId).orElseThrow(() -> new InvalidRequestException("User not found"));
user.updateRole(UserRole.of(userRoleChangeRequest.getRole()));
}
}
유저의 role를 변경하는 코드인데 여기서 findById로 유저를 찾고 밑에서 User Entity의 updateRole 메서드로 role를 변경한다. 그리고 userRepository.save()를 호출하는게 아니여도 변경사항이 데이터베이스에 정상적으로 적용된다.
내가 찾은 이유. (명확하지 않을 수 있어서 나중에 더 찾아보고 수정해야할 수도 있음.)
@Transactional 어노테이션에 의해 changeUserRole 메서드를 호줄한 순간 트랜잭션이 시작한다.
updateRole 메서드는 User 엔티티 객체의 속성을 변경하게 되는데, 이때 Spring Data JPA에서 엔티티의 상태가 변경되면, 엔티티 매니저는 자동으로 변경사항을 감지하고, 트랜잭션이 종료될 때 데이터베이스에 반영한다.(더티 체킹)
위의 말을 자세하게 풀면
트랜잭션이 정상적으로 종료되면 Spring 프레임워크는 엔티티 매니저에게 트랜잭션을 커밋하도록 지시.
하지만 트랜잭션이 커밋되기 전에, 엔티티 매니저는 영속성 컨텍스트에서 관리하는 엔티티의 변경사항을 감지한다.
감지된 변경사항은 트랜잭션이 커밋될 때 데이터베이스에 반영된다.
즉, 트랜잭션이 커밋되는 시점에 더티 체킹이 작동하여 엔티티 매니저가 감지한 변경사항을 데이터베이스에 저장하는 것
@Transactional 어노테이션이 없다면
- 트랜잭션이 시작되지 않음: 메서드 호출 시 트랜잭션이 시작되지 않기 때문에, 변경사항이 자동으로 데이터베이스에 커밋되지 않는다.
- 자동 플러시: 트랜잭션이 없으면 Hibernate와 같은 ORM 프레임워크는 자동으로 데이터 변경을 데이터베이스에 반영하지 않는다.
'spring' 카테고리의 다른 글
| 테스트 코드 (0) | 2025.03.06 |
|---|---|
| 페이징처리할때 수동으로 처리하면서 공부한 내용 (0) | 2025.03.05 |
| 관계형DB일때 N:M 연관관계 @ManyToMany (0) | 2025.02.24 |
| @Mock (0) | 2025.02.24 |
| 뉴스피드 트러블슈팅 (0) | 2025.02.16 |