본문 바로가기
Spring

@Transactional에 대해서 알아보자

by Jammini 2023. 12. 4.
728x90

목차

  1. 트랜잭션이란?

  2. 스프링에서 @Transactional

  3. 테스트 환경에서의 @Transactional

  4. 결론

1. 트랜잭션이란?

우리말로 ‘거래’라는 뜻을 가지고 있으며 다음과 같다.

  • 단일한 논리적인 작업 단위

  • 논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든 것이 트랜잭션이다.

  • 트랜잭션이 SQL문들 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.

A가 B에게 10000원 입금을 하는 상황을 가정해보자.

  1. A는 통장에서 10000원이 출금된다.

  2. B는 통장에서 10000원이 입금된다.

이처럼 2가지 작업이 모두 정상적으로 성공해야만 하나의 상황으로 묶는 것을 트랜잭션이다.

모든 작업들이 성공적으로 완료 되어야 결과를 적용하고, 어떤 작업에서 오류가 발생했을 때는 이전에 모든 작업들이 성공적이었더라도 없었던 일처럼 되돌리는 것이 트랜잭션의 개념이다.

2. 스프링에서 @Transactional

DB와 관련된, 트랜잭션이 필요한 서비스 클래스 혹은 메서드에 @Transactional 어노테이션을 달아주면된다.

@Transactional이 붙은 메서드는 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소한다.

프록시를 통한 문제 해결

서비스에 비즈니스 로직과 트랜잭션 로직이 함께 섞여있다.

image

트랜잭션 프록시가 트랜잭션 처리 로직을 모두 가져간다. 그리고 트랜잭션을 시작한 후에 실제 서비스를 대신 호출한다. 트랜잭션 프록시 덕분에 서비스 계층에는 순수한 비즈니스 로직만 남길 수 있다.

image

프록시를 사용하면 트랜잭션을 처리하는 객체와 비즈니스 로직을 처리하는 서비스 객체를 명확하게 분리할 수 있다.

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

3. 테스트 환경에서의 @Transactional

테스트 메서드에 @Transactional을 사용하면 트랜잭션으로 감싸지며, 메서드가 종료될 때 자동으로 롤백된다.

@Transactional 원리

스프링이 제공하는 @Transactional 애노테이션은 로직이 성공적으로 수행되면 커밋하도록 동작한다.

그런데 @Transactional 애노테이션을 테스트에서 사용하면 아주 특별하게 동작한다. @Transactional 이 테스트에 있으면 스프링은 테스트를 트랜잭션 안에서 실행하고, 테스트가 끝나면 트랜잭션을 자동으로 롤백시켜 버린다

1. 테스트에 @Transactional 애노테이션이 테스트 메서드나 클래스에 있으면 먼저 트랜잭션을 시작한다. 2. 테스트를 로직을 실행한다. 테스트가 끝날 때 까지 모든 로직은 트랜잭션 안에서 수행된다.

  • 트래잭션은 기본적으로 전파되기 때문에, 리포지토리에서 사용하는 JdbcTemplate도 같은 트랜잭션을 사용한다.

3. 테스트 실행 중에 INSERT SQL을 사용해서 item1 , item2 , item3 를 데이터베이스에 저장한다. 물론 테스트가 리포지토리를 호출하고, 리포지토리는 JdbcTemplate을 사용해서 데이터를 저장한다.

4. 검증을 위해서 SELECT SQL로 데이터를 조회한다. 여기서는 앞서 저장한 item1 , item2 , item3 이 조회되었다.

  • SELECT SQL도 같은 트랜잭션을 사용하기 때문에 저장한 데이터를 조회할 수 있다. 다른 트랜잭션에서는 해당 데이터를 확인할 수 없다.

  • 여기서 assertThat() 으로 검증이 모두 끝난다.

5. @Transactional 이 테스트에 있으면 테스트가 끝날때 트랜잭션을 강제로 롤백한다. 6. 롤백에 의해 앞서 데이터베이스에 저장한 item1 , item2 , item3 의 데이터가 제거된다.

4. 결론

  • 일련의 작업들을 묶어서 하나의 단위로 처리하고 싶다면 @Transactional을 활용하자.

  • @Transactional 덕분에 아주 편리하게 다음 원칙을 지킬수 있게 되었다.

    • 테스트는 다른 테스트와 격리해야 한다.

    • 테스트는 반복해서 실행할 수 있어야 한다.

  • 프로덕션 환경과 테스트 환경의 동작 방식을 유념하여 사용하자.

Uploaded by

N2T

반응형