@Transactional

2024. 6. 24. 16:32Java/Spring

@Transactional 

  • 스프링 프레임워크에서 트랜잭션을 처리하는데 사용되는 중요한 어노테이션입니다. 이 어노테이션은 메서드나 클래스에 적용할 수 있으며, 해당 메서드나 클래스가 하나의 트랜잭션 단위로 실행되어야 함을 스프링에게 알려줍니다.

트랜잭션이란?

  • 데이터베이스 트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다.
  • 데이터베이스의 상태를 변경시키기 위해 수행하는 작업 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산을 의미한다.

 

  • 트랜잭션 경계 설정:
    • @Transactional 어노테이션이 적용된 메서드가 실행될 때, 스프링은 트랜잭션을 시작하고 메서드 실행이 완료될 때까지 트랜잭션을 유지합니다. 이를 통해 데이터베이스 작업이 원자적(Atomic)으로 처리될 수 있습니다.
  • 예외 처리와 롤백:
    • @Transactional 어노테이션이 적용된 메서드에서 예외가 발생하면, 스프링은 자동으로 해당 트랜잭션을 롤백시킵니다. 따라서 데이터베이스와 같은 리소스에서 발생할 수 있는 문제에 대비하여 안정적인 트랜잭션 관리를 제공합니다.
  • 트랜잭션 속성 설정:
    • @Transactional 어노테이션은 다양한 속성을 설정하여 트랜잭션의 동작을 세밀하게 제어할 수 있습니다. 예를 들어, isolation 레벨, propagation 방식, timeout 설정 등을 지정할 수 있습니다.

 

 

 

@Transactional 사용 예제

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void updateUser(User user) {
        userRepository.save(user);
        // 다른 데이터베이스 작업 수행 가능
    }

    @Transactional(readOnly = true)
    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }
}

 

 

@Transactional 어노테이션 속성

@Transactional(readOnly = true)
public User getUserById(Long userId) {
    return userRepository.findById(userId).orElse(null);
}
속성 내용
readOnly 기본값은 false이며, 읽기 전용 트랜잭션으로 설정할 수 있습니다. 이 경우 데이터베이스에서 조회만 수행하고 수정은 할 수 없습니다.
isolation 트랜잭션 격리 레벨을 설정할 수 있습니다. 기본값은 Isolation.DEFAULT입니다.
propagation 트랜잭션 전파 방식을 설정합니다. 다른 트랜잭션 내에서 호출될 때의 동작을 결정합니다.
timeout 트랜잭션 타임아웃 시간(초 단위)을 설정할 수 있습니다. 기본값은 -1로, 무제한을 의미합니다.
rollbackFor
noRollbackFor
롤백할 예외 클래스를 설정할 수 있습니다.

 

 

@Transactional 주의 사항

  • @Transactional 어노테이션은 스프링의 AOP (Aspect-Oriented Programming) 기능을 기반으로 동작합니다. 따라서 이 어노테이션이 적용되기 위해서는 스프링이 적절한 AOP 설정을 해주어야 합니다.
  • 클래스 레벨에 @Transactional을 선언하면 해당 클래스의 모든 public 메서드에 적용됩니다.

@Transactional 어노테이션을 사용하여 데이터베이스 트랜잭션을 관리하면 데이터 일관성과 안정성을 유지하면서 비즈니스 로직을 구현할 수 있습니다.

 

 

 

@Transactional(readonly = true)

  • (readonly = true)가 적용된 메서드와 관련된 트랜잭션이 읽기 전용임을 나타냅니다. 이는 성능 최적화에 유용하며, 해당 범위 내에서 데이터베이스에 변경 사항이 발생하지 않도록 보장하는 데 사용됩니다.

장점

  1. 성능 최적화: 읽기 전용 트랜잭션은 데이터베이스에 불필요한 쓰기 락을 방지하여 성능을 향상시킬 수 있습니다.
  2. 무결성 유지: 읽기 전용 트랜잭션 내에서 데이터가 변경되지 않도록 보장하여 데이터 무결성을 유지할 수 있습니다.

예제

@Service
public class MyService {

    @Transactional(readonly = true)
    public List<MyEntity> findAll() {
        // 데이터베이스에서 엔티티 목록을 읽어오는 로직
    }
}

위의 코드에서 findAll 메서드는 읽기 전용 트랜잭션 내에서 실행되므로, 데이터베이스에서 데이터를 읽어오는 동안 데이터 변경이 발생하지 않습니다.