본문 바로가기

카테고리 없음

[Spring] @Transactional 과 AOP

반응형

@Transactional

Spring 에서 제공하는 어노테이션의 종류로, 클래스 / 메서드 / 인터페이스 위에 추가하여 사용한다.

만약 메서드에 추가된다면 해당 메서드에 대해 내부적으로 AOP를 통해 트랜잭션 처리 코드가 전후로 수행된다.

 

트랜잭션의 필요성

체스 게임을 개발한다고 가정해보자.

새 게임이 시작될 때마다 초기화 된 체스판(1)과 새로운 체스말(2)이 필요할 것이다.

 

만약 트랜잭션이 없다면 체스판은 초기화되어 제공(1)되더라도 체스말(2)이 세팅되지 않는 경우가 발생할 수 있다.

1번과 2번 요청을 개별적으로 요청하게 된다면, 데이터베이스 입장에서는 두 요청을 별개의 작업으로 처리할 수 있다.

 

따라서 하나의 트랜잭션 단위로 묶어서 아래와 같이 하나의 세션으로 데이터베이스에 요청해야한다.

 

 

위 요청을 코드로 구현해보면 아래와 같다.

 

프로그래밍 방식 트랜잭션 관리

 

@Override
public GameCreateResponse create(GameCreateRequest request) throws SQLException {
	
    Connection con = dataSource.getConnection();
    con.setAutoCommit(false);
    
    try {
    	request.setRoomPassword(passwordEncoder.encode(request.getRoomPassword()));
        Room room = roomRepository.save(con, request);
        boardRepository.save(con, room.getId());
        
        GameCreateReponse reponse = new GameCreateReponse(room.getId());
        
        con.commit();
        
        return reponse;
    } catch (Exception e){
    	con.rollback();
        throw new ChessException();
    }
}

 

 

이렇게 수행하면 기능에 오류는 없지만, 여러 단점들이 존재한다.

  • 매번 트랜잭션 처리 코드를 추가해야 하기 때문에, 중복 코드가 많아짐
  • 코드 작성 시 실수가 발생할 여지가 많아짐
  • 주된 관심사가 아닌 코드가 서비스 레이어에 담김
  • 특정 기술에 종속적인 코드임
    • SQLException은 JDBC에 종속된 객체이다.

 

@Transactional 사용 이유

빈 생성 시, @Transactional 애너테이션이 있으면 프록시 객체가 빈으로 등록된다.

위의 프로그래밍 방식 트랜잭션 관리와는 다르게 스프링이 제공하는 선언적 트랜잭션 관리라고도 한다.

따라서 서비스 레이어에 트랜잭션 관련된 코드 혹은 특정 기술에 종속된 코드를 분리해준다.

 

선언전 트랜잭션 관리

@Transactional
@Service
public class ChessService {
	
    @Override
    public GameCreateResponse create(GameCreateRequest request) {
        request.setRoomPassword(passwordEncoder.encode(request.getRoomPassword()));
        Room room = roomRepository.save(request);
        
        boardRepository.save(room.getId());
        return new GameCreateReponse(room.getId());
    }
}

 

 

reference

- https://youtu.be/taAp_u83MwA

반응형