@Transactional은 스프링 프레임워크에서 제공하는 어노테이션으로, 주로 데이터베이스 트랜잭션 관리를 위해 사용된다. 이 어노테이션을 사용하면 메서드나 클래스가 트랜잭션 내에서 실행되도록 설정할 수 있다. 트랜잭션은 일련의 데이터베이스 작업들을 하나의 단위로 묶어서, 전체 작업이 성공하면 커밋(commit)하고, 중간에 실패하면 롤백(rollback)하여 데이터의 일관성과 무결성을 보장한다.
트랜잭션 시작과 종료: @Transactional이 적용된 메서드가 호출되면, 스프링은 트랜잭션을 시작하고, 메서드가 정상적으로 완료되면 트랜잭션을 커밋한다. 만약 예외가 발생하면 트랜잭션을 롤백한다.
예외 처리: 기본적으로 RuntimeException 및 그 하위 클래스가 발생할 경우 트랜잭션이 롤백된다. 그러나 특정 예외에 대해 롤백 또는 커밋 동작을 커스터마이징할 수 있다.
전파(Propagation): 트랜잭션이 이미 진행 중일 때 새로운 트랜잭션을 시작할지, 기존 트랜잭션에 참여할지, 아니면 별도의 트랜잭션으로 처리할지 등을 설정할 수 있다.
격리 수준(Isolation Level): 데이터 일관성을 유지하기 위해 트랜잭션 격리 수준을 설정할 수 있다. 이는 트랜잭션이 다른 트랜잭션과 어떤 방식으로 상호작용할지 정의한다.
클래스에 @Transactional을 적용하면 클래스의 모든 public 메서드에 트랜잭션이 적용된다.
@Service
@Transactional
public class UserService {
public void createUser(User user) {
// 트랜잭션 시작
// 사용자 생성 로직
// 트랜잭션 커밋 또는 롤백
}
public User getUser(Long id) {
// 트랜잭션 시작
// 사용자 조회 로직
// 트랜잭션 커밋 또는 롤백
}
}
특정 메서드에만 트랜잭션을 적용하고자 할 때는 메서드에 @Transactional을 직접 지정할 수 있다.
@Service
public class OrderService {
@Transactional
public void placeOrder(Order order) {
// 트랜잭션 시작
// 주문 처리 로직
// 트랜잭션 커밋 또는 롤백
}
public Order getOrder(Long id) {
// 이 메서드에는 트랜잭션이 적용되지 않음
// 주문 조회 로직
}
}
트랜잭션 전파 및 격리 수준을 설정하여 더욱 정밀하게 트랜잭션 동작을 제어할 수 있다.
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)
public void processPayment(Payment payment) {
// 트랜잭션 시작
// 결제 처리 로직
// 트랜잭션 커밋 또는 롤백
}
데이터 무결성 보장: 데이터베이스 작업을 수행할 때, 일관성 있는 상태를 유지해야 할 경우에 사용한다. 예를 들어, 은행 계좌 이체에서 출금과 입금 작업이 모두 성공해야 하는 경우.
에러 처리: 작업 중 오류가 발생했을 때, 이전 작업들을 원상태로 돌려야 할 때 사용한다. 예를 들어, 여러 테이블에 데이터를 삽입하는 작업에서 중간에 오류가 발생했을 때, 이미 삽입된 데이터를 모두 롤백해야 하는 경우.
복잡한 비즈니스 로직: 여러 데이터베이스 연산이 하나의 논리적 작업 단위로 묶여야 하는 경우에 사용한다.