[Spring] @Transactional 을 쓰는 이유와 개념

백엔ㄷ현·2024년 10월 23일

@Transactional 은 스프링 프레임워크에서 데이터베이스와의 트랜잭션 관리를 쉽게 하기 위해 제공하는 어노테이션이다. 트랜잭션은 데이터베이스 작업의 논리적인 단위를 의미하며, 원자성을 보장한다.

원자성?:
모든 작업이 성공하거나, 실패 시 모든 변경이 롤백되는 성질



@Transactional 을 사용의 장점

  • 원자성 보장 :

    트랜잭션 내의 모든 작업이 성공해야만 데이터베이스에 반영되며, 하나라도 실패하면 모두 롤백된다.
  • 자동 커밋/롤백 :

    메소드가 정상적으로 끝나면 자동으로 커밋, 예외가 발생하면 자동으로 롤백한다.
  • 트랜잭션 관리 간소화 :

    코드 내에서 명시적으로 커밋, 롤백을 구현하지 않아도 되어 관리가 간편해진다.


예시 코드

UserService.java

@Service
@RequiredArgsConstructor
public class UserService {

	private final UserRepository userRepository;
    private final ProfileRepository profielRepository;
    
    @Transactional
    public User registerUser(UserRegisterRequest request) {
    	// 이메일 중복 확인
        if(userRepository.existsByEmailAndStatus(request.getEmail(), "ACTIVE")) {
        	throw new IllegalArgumentException("이미 사용 중인 이메일입니다.");
        }
        
        // 비밀번호 확인
        if (!request.getPassword().equals(request.getConfirmPassword())) {
        	throw new IllegalArgumentException("비밀번호가 일치하지 않습니다");
        }
        
        // 사용자 생성 및 저장
        User user = new User();
        user.setEmail(request.getEmail());
        user.setPassword(request.getPassword());
        user.setUsername(request.getUsername());

        // 사용자 저장
        User savedUser = userRepository.save(user);

        // 프로필 생성 (회원가입 시 자동 프로필 생성)
        profileService.createProfile(savedUser);

        return savedUser;
    }
}

ProfileService.java

@Service
@RequiredArgsConstructor
pubic class ProfileService {
	
    private final ProfileRepository profileRepository;
    
    @Transactional
    public void createProfile(User user) {
    	profile profile = Profile.builder()
        		.user(user)
                .bio("자기소개를 입력해주세요.")
                .profileImage("/images/basic-profile.png")
                .follower(0L)
                .following(0L)
                .build();
                
        profileRepository.save(profile);
    }
}
  • @Transactional :

    위 코드에서 회원가입과 프로필 생성이 동일한 트랜잭션 내에서 처리되므로 원자성을 보장해야 한다. 회원가입 도중에 예외가 발생할 경우, 프로필 생성 작업 역시 롤백되어야 데이터의 무결성을 지킬 수 있게된다.

    예를 들어, 사용자가 회원가입을 하다가 예외가 발생하면, 이미 저장된 사용자 정보와 프로필을 자동으로 롤백하게 되는 것이다.

    • 원자성 보장 :
      회원가입 과정에서 프로필 생성에 실패하면, 사용자 정보도 저장되지 않도록 전체 작업을 취소할 수 있다.

    • 자동 커밋 및 롤백 :
      모든 작업이 정상적으로 수행되었을 경우, 자동으로 데이터베이스에 커밋하고 예외가 발생할 경우 데이터베이스 변경을 자동으로 롤백한다.


@Transactional 옵션

  • propagation :

    트랜잭션의 전파 수준을 지정한다. REQUIRED 는 기존 트랜잭션을 사용할 수 있으면 사용하고 없으면 새로 생성한다.
  • readOny :

    true 로 설정하면 읽기 전용 트랜잭션을 만든다. 이렇게 하면 성능 최적화가 가능하고, 쓰기 작업 시 예외가 발생한다.
  • rollbackFor :

    특정 예외가 발생했을 떄 롤백하도록 설정할 수 있다.
profile
매일매일 공부한 내용과 코드 기록하겠습니다

0개의 댓글