@Transactional 을 왜 사용하나요

SionBackEnd·2023년 2월 21일
0

Spring(봄)

목록 보기
18/22

@Transactional 을 왜 사용하나요

만약 스프링에서 지원하는 Transactional 어노테이션 사용하지 않으면 트랜잭션을 직접 구현해 주어야 한다.

먼저 서비스로직에는 데이터베이스 커넥션풀을 얻어서 트랜잭션을 시작할때 수동 커밋 옵션을 켜고, 해당 서비스 로직이 종료되지 전까지 동일한 커넥션 풀을 유지 시켜주어야 하며 예외없이 성공한다면 커밋 후 수동 커밋 옵션을 자동 커밋 옵션으로 변경해 주어야 한다. (디포트값이 자동 커밋이라 다른 개발자가 햇갈릴 수 있다. 여기서 알 수 있는점은 생성된 커넥션 풀은 설정한 옵션을 유지 한다는 점이다.)

또한 예외가 발생한다면 롤백을 시켜주어야 하며 try catch final 문을 이용하여 작성한다. 가장 큰 문제는 실질적인 서비스 로직보다 트랜잭션 처리해주는 로직의 비중이 더 크며 하나의 서비스 로직만이 아닌 모든 서비스 로직에 동일하게 공통의 트랜잭션 코드가 작성된다는 것이다. (중복)

그리고 jdbc의 트랜잭션 로직과 jpa의 트랜잭션 로직이 다르기 때문에 만약 jdbc에서 jpa로 변경한다면, 모든 서비스 로직의 트랜잭션 로직을 변경해주어야 한다는 절망적인 사실이 존재한다.

스프링은 플랫폼 트랜젝션 메니저를 통해서 커밋 롤백 메서드를 인터페이스화 시키고 트랜잭션 동기화 매니저를 통해 초창기 방식처럼 커넥션을 개발자가 직접 이어주지 않아도 되는 편리함을 얻게 되었다.(트랜잭션 동기화 매니저는 Thread Local을 이용하여 커넥션을 동기화 해준다.)

하지만 그럼에도 여전히 문제는 try / catch 문으로 롤백시 개발자가 직접 트랜젝션 매니저의 rollback 메서드를 작성해야 하는것이다. 이것은 서비스 로직에 순수한 비즈니스 로직만을 작성하는것이 아니고, 또한 유지보수시에도 만약 트랜잭션이 필요없어지는 메서드가 존재한다면, try / catch문을 직접 제거해주어야 한다는 유지보수의 불편함이 아직도 남아있다는 것이다.

그래서 Spring은 트랜잭션을 AOP를 통해 프록시를 도입시켜 서비스 로직에 순수 서비스 로직만을 남길 수 있게 하였다. 그것이 바로 @Transactional이다.

개발자는 트랜잭션 처리가 필요한 곳에 @Transactional 어노테이션만 붙여주면 된다. 스프링의 트랜잭션 AOP는 이 어노테이션을 인식해서 트랜잭션 프록시를 적용해준다. (트랜잭션이 적용된 서비스로직을 프록시로 만든다.)

클라이언트가 해당 서비스로직을 호출 시 스프링은 먼저 프록시 서비스 로직을 호출하고 그곳에 작성되어있는 트랜잭션 메니저 호출 메서드가 실행된다. 그리고 오토커밋(false) 메서드를 통해서 트랜잭션을 시작한다. 여기서 중요한점은 트랜잭션 동기화 매니저에게 커넥션을 보관한다는 점이다. 그리고 실제 비즈니스 로직을 호출하고 그 비즈니스 로직은 리포지토리에 접근하여 보관 되어있는 커넥션을 사용한다. 데이터가 정상적으로 커밋이 되었다면 트랜잭션을 종료하고 아니라면 롤백시킨다. 그리고 클라이언트에게 결과 값을 전달한다.

이렇게 많은 역사와 흐름을 통해서 우리가 간단히 @Transactional 어노테이션만으로도 트랜잭션을 실행 시킬 수 있게 된것이다.

장문의 글로 작성하여 가독성이 많이 떨어지지만 대략적인 흐름이 이해가 갔다면 작전 성공이다. 만약 자세히 더욱 알고싶다면 아래의 사이트를 참조하자.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1

profile
많은 도움 얻어가시길 바랍니다!

0개의 댓글