-
@Transactional 어노테이션이란?Spring Framework 2022. 9. 14. 00:01728x90
트랜잭션이란?
트랜잭션이란 데이터베이스에 자주 보이는 용어입니다.
트랜잭션은 "하나의 일련의 연산이 모두 반영되거나 아니만 아예 아무것도 반영되지 않아야 합니다"
예를 들면 A -> B에게 송금을 하는 상황을 떠올리면 좋습니다.
A의 계좌에서 일정 금액이 빠져나가면 B계좌에는 일정 금액이 들어와야 합니다.
만약 A의 계좌에서 일정금액 출금되고 B계좌에는 입금되지 않는다면 은행은 큰 신뢰를 잃어버리게 됩니다.
이때 작업단위를 다음과 같이 구분해보겠습니다.
작업 1은 A의 출금
작업 2는 B의 입금
각각의 작업은 서로 다른 DB Connection으로 이루어질 수 있기 때문에 이 두 작업을 트랜잭션으로 묶어주어야 합니다.
트랜잭션의 적용
@Transactional을 적용하지 않고 트랜잭션을 적용하기 위해서는 JDBC에서 connection을 가져와서 하나의 connection에 작업 1, 작업 2를 수행하고 이를 commit 해야 합니다.
또한 이 과정중에 Exception이 발생하면 rollback을 수행해주어야 하기 때문에 try-catch도 사용될 수 있습니다.
이렇게 코드 작성이 많아지고 트랜잭션을 적용하기 위해 중복 코드가 많아집니다.
또한 exception에 따라 특정 기술에 종속적인 코드가 될 수 있습니다. (ex. SQLException은 JDBC에서만 사용됨)
AOP 등장
트랜잭션의 시작 -> {실제 비즈니스 로직 수행} -> 커밋 또는 롤백
우리의 주 관심하는 비즈니스 로직입니다.
따라서 프록시를 활용한 기술인 AOP를 활용해 중복된 코드를 줄여주고자 했습니다.
이제는 스프링을 사용하면 중복된 코드 대신에 @Transactional 어노테이션을 사용하면 됩니다.
테스트 환경에서의 @Transactional 동작
테스트 메서드에 @Transactional 어노테이션을 사용하면 메서드가 종료될 때 자동으로 롤백됩니다.
하지만 Auto Increment 옵션으로 사용되는 id는 트랜잭션 범위 밖에서 동작하기 때문에 롤백되지 않습니다.
https://junuuu.tistory.com/372
Spring Data JPA와 @Transactional
Spring Data JPA가 제공하는 Repository의 모든 메서드는 @Transactional이 적용되고 있습니다.
Spring Data JPA를 사용하여 변경감지를 활용한 update를 수행하려고 하였지만 제대로 업데이트가 되지 않는 상황이 있었습니다.
Repository에 @Transactional이 적용되어 있다고 생각하여 Service Layer에 @Transactional을 사용하지 않은 것이 문제였습니다.
이미 Repository를 통해 Entity가 조회되고 영속성 콘텍스트가 끝나버리게 되면 이후에 update 하는 부문이 실행되지 않았기 때문입니다.
따라서 Service Layer에도 메서드 부분에 @Transactionl 어노테이션을 활용하여 해결할 수 있었습니다.
@Transactional 옵션
1. isolation : 고립레벨 설정
2. propagation : 트랜잭션 동작 도중 다른 트랜잭션을 호출할 때, 어떻게 할 것인지 지정하는 옵션
3. noRollbackFor : 특정 예외 발생 시 rollback 하지 않음
4. rollbackFor : 특정 예외 발생 시 rollback
5. timeout : 지정한 시간 내에 메서드 수행이 완료되지 않으면 rollback
6. readOnly : 트랜잭션을 읽기 전용으로 설정
출처
https://www.youtube.com/watch?v=taAp_u83MwA
https://tecoble.techcourse.co.kr/post/2021-05-25-transactional/
https://velog.io/@kdhyo/JavaTransactional-Annotation-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-26her30h
'Spring Framework' 카테고리의 다른 글
Spring 버전에 맞는 Dependency 버전 찾기 (0) 2023.02.06 토비의 스프링 부트 강의 요약 (0) 2023.01.29 @SpringBootApplication의 역할 (0) 2022.06.24 @Bean vs @Component (0) 2022.05.24 필터와 인터셉터의 차이점 (0) 2022.05.22