728x90

개요

프로젝트 중

@Transactional 을 안 붙여서 오류가 나는 경우가 종종 있어서 이번 기회에 정리해놓을려고 한다.


@Transactional

 

Q. @Transactional 어노테이션 붙이는 이유?

  • 데이터베이스의 상태를 변경하는 메서드나 복수의 데이터베이스 작업을 묶어서 처리할 때 사용한다.
  • 데이터를 데이터베이스에 저장하거나 삭제, 수정하는 메서드처럼 데이터베이스의 상태를 변경하는 경우에 사용한다.

 

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final RoleRepository roleRepository;
    private final PasswordEncoder passwordEncoder;

    @Transactional
    public void registerUser(String username, String email, String password, String passwordCheck, String usernick) throws IOException {
        
        Role role = roleRepository.findByRoleName(RoleName.ROLE_USER)
                    .orElseThrow(() -> new UserNotFoundException("User 역할이 없습니다."));
 
        User user = new User();
        user.setRole(Collections.singleton(role));  // singleton -- 단일 역할 설정
        user.setUserName(username);
        user.setEmail(email);
        user.setPassword(passwordEncoder.encode(password));
        user.setUserNick(usernick);

        userRepository.save(user);
    }

 @Transactional

  • 메서드가 실행되는 동안 트랜잭션을 시작하고, 메서드가 정상적으로 완료되면 커밋(commit)을 하고, 예외가 발생하면 롤백(rollback)을 수행한다.
  • 이 어노테이션을 사용하여 데이터베이스 관련 작업을 안전하게 처리할 수 있다.
  • 기본 값 : @Transactional(readOnly = false)
    • 특징: 위의 예시에서는 registerUser 메서드에 적용되어 있으며, readOnly = false로 설정되어 있어 해당 메서드는 읽기/쓰기 모두 가능한 트랜잭션을 사용합니다.

 

readOnly 속성의 차이점

  1. readOnly = true
    • 이 옵션을 설정하면, 트랜잭션 동안 데이터를 수정하는 쿼리(INSERT, UPDATE, DELETE 등)를 수행할 수 없다.
    • 오직 읽기 전용 쿼리(SELECT)만 가능
    • 데이터를 조회만 할때, 전체 사용자, 게시글 조회 등등
    • 이는 데이터베이스에게 현재 트랜잭션이 데이터를 변경하지 않을 것임을 알려 성능 최적화를 도와준다.
    • 읽기 전용 트랜잭션은 데이터베이스의 트랜잭션 로그를 기록하지 않아도 되어 I/O 부하를 줄일 수 있다.
  2. readOnly = false (기본값)
    • 읽기 및 쓰기 작업 모두를 수행할 수 있는 트랜잭션
    • 데이터베이스에 변경 사항이 발생하면 트랜잭션 로그 기록
    • 쓰기 작업이 필요한 경우에는 이 옵션을 사용
    • 삭제, 등록, 수정 등 데이터베이스의 상태를 변경할 때 사용한다.

 

결론 

데이터베이스에서 삽입, 삭제, 수정 등 데이터베이스의 내용이 변하게 된다면 @Transactional 붙여야 한다.!!

728x90

+ Recent posts