[Spring] @Transactional 트랜잭션 처리

류넹·2024년 3월 12일
1

Spring

목록 보기
32/50

❓ DB Transaction

  • 여러번의 DB Access 작업을 하나의 논리적인 작업 그룹으로 만들고,
    그 그룹을 DB에 일괄적으로 전체반영/전체취소 되도록 만들어주는 단위
    부분적인 성공/취소를 허용하지 않음


📌 @Transactional

선언적 트랜잭션 처리를 지원하는 어노테이션(보통 Service에 부착)

  • 데이터의 일관성을 유지하기 위해 트랜잭션을 처리한다.


✔️ @Transactional 특징

  • @Transactional 어노테이션은 인터페이스, 클래스, 메소드에 붙일 수 있다.
    • 인터페이스에 지정하면 해당 인터페이스를 구현한 구현객체의 각 메소드가 실행될 때마다 트랜잭션처리가 지원된다.
    • 클래스에 지정하면 해당 클래스로 생성한 객체의 각 메소드가 실행될 때마다 트랜잭션처리가 지원된다.
    • 메소드에 지정하면 해당 메소드가 실행될 때마다 트랜잭션처리가 지원된다.

  • 선언적 트랜잭션 처리가 지원되면 해당 메소드가 실행되기 전에 새로운 트랜잭션이 시작된다.
    • 트랜잭션이 시작된다는 말은, 데이터베이스에서 지금부터 실행하는 모든 SQL 구문의 하나의 논리적인 그룹으로 묶을 준비가 되었다는 것이다.
    • 메소드 내에서 데이터베이스 액세스 작업을 할 때마다 해당 SQL작업을 트랜잭션에 추가한다.

  • 선언적 트랜잭션 처리가 지원되면 해당 메소드가 종료될 때 트랜잭션을 종료한다.
    • 해당 메소드를 실행하면서 RuntimeException의 하위 예외가 발생하면 해당 트랜잭션에 추가된 모든 작업에 대해서 rollback을 실행한다.
      (* RuntimeException 및 그 하위 예외가 아니라면 Exception의 하위여도 해당 안됨)
    • 해당 메소드를 실행하면서 예외가 발생하지 않으면 해당 트랜잭션에 추가된 모든 작업에 대해서 commit을 실행한다.



💡 예시)

  • Class 파일에 @Transactional 어노테이션 부착
@Service
@Transactional
public class UserService {

	@Autowired
	private UserDao userDao;
	
	public void registerUser(User user) {
		User savedUser = userDao.getUserById(user.getId());
		if (savedUser != null) {
			throw new RuntimeException("["+user.getId()+"] 아이디가 이미 사용중입니다.");
		}
		
		userDao.insertUser(user);
	}
	
	public User getUserDetail(String id) {
		User savedUser = userDao.getUserById(id);
		if (savedUser == null) {
			throw new RuntimeException("["+id+"] 아이디에 해당하는 사용자 정보를 찾을 수 없습니다.");
		}
		return savedUser;
	}
}
profile
학습용 커스터마이징 간단 개발자 사전

0개의 댓글