✔ readOnly (읽기 전용)

읽기 전용 트랜잭션을 설정하면 JPA가 데이터를 변경하지 않도록 최적화합니다.

@Transactional(readOnly = true)
public User getUser(Long id) {
    return userRepository.findById(id).orElseThrow();
}

🚀 효과

✔ propagation (전파 옵션)

트랜잭션이 존재할 때, 새로운 트랜잭션을 어떻게 처리할지를 결정합니다.

전파 옵션 설명
REQUIRED (기본값) 기존 트랜잭션이 있으면 그대로 사용, 없으면 새로 생성
REQUIRES_NEW 기존 트랜잭션을 무시하고 새 트랜잭션 생성
MANDATORY 반드시 기존 트랜잭션이 있어야 함 (없으면 예외 발생)
SUPPORTS 트랜잭션이 있으면 참여, 없으면 트랜잭션 없이 실행
NOT_SUPPORTED 트랜잭션 없이 실행 (기존 트랜잭션이 있으면 일시 중지)
NEVER 트랜잭션이 있으면 예외 발생

🛠 REQUIRES_NEW 예제

기존 트랜잭션과 별도로 실행해야 하는 경우 REQUIRES_NEW를 사용하면, 한 트랜잭션이 롤백되어도 다른 트랜잭션은 유지됩니다.

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private LogService logService;

    @Transactional
    public void createUser(String name) {
        userRepository.save(new User(name));

        logService.logTransaction(name);  // 별도 트랜잭션 실행

        if (name.equals("error")) {
            throw new RuntimeException("강제 예외 발생");
        }
    }
}

@Service
public class LogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logTransaction(String message) {
        System.out.println("로그 저장: " + message);
        // 예외가 발생해도 기존 트랜잭션과 독립적
    }
}

✔ 실행 결과

✔ isolation (격리 수준)

여러 트랜잭션이 동시에 실행될 때, 데이터 정합성을 유지하기 위한 설정입니다.