hello world

@Transactional 어노테이션 본문

WEB/Spring .Spring Boot

@Transactional 어노테이션

sohyun_92 2022. 7. 14. 09:49
728x90

트랜잭션에 대해 결제와 같은 상황을 예를 들어 말하자면

 

"결제는 다른사람과 독립적으로 이루어지며, 과정 중에는 다른 연산이 끼어들수없다. 오류가 생긴 경우 연산을 취소하고 원래대로 돌린다. 성공할경우 결과를 반영한다." 

 

ACID(원자성,일관성,고립성,지속성) 

 

 

@Transactional 어노테이션 이란?!

아래와 같이  클래스나 메서드에 붙여서 사용한다. 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다.

 @Transactional
    public resDto getData(String Id) {
         .... 
         로직 생략
    }

 - 다른 연산과 혼선으로 잘못된 값을 가져오는 경우 방지

 (내가 transactional 어노테이션을 사용하게 된 이유.. 배치로 주기적으로 실행되는 값과 혼선으로 에러가 발생했었다.)

- 연산의 원자성 보장, 연산이 도중 실패할 경우 변경사항 commit 안함 

 

 

@Transactional 어노테이션의 동작방식 

 @Transactional 포함된 메서드가 호출되면, TransactionalManager를 사용하여 트랜잭션을 시작한다.

메서드가 실행하기 전 begin을 호출하고, 메서드가 종료된 뒤 commit을 호출한다. 비정상일 경우, Rollback한다.

 

 

@Transactional 어노테이션 사용시 주의사항

1. @Transactional 을 달아놓은 메소드가 동일한 클래스 내의 다른 메소드에 의해 호출된다면 트랜잭션이 정상 작동하지 않는다.

ex: (퍼사드 패턴이나 템플릿 패턴처럼 여러 메소드를 내부적으로 묶어 사용하고 있는 메소드가 있다면 구성요소 메소드에 @Transactional 를 달지 않고 구성요소를 묶고 있는 상위개념의 메소드에 @Transactional 을 달아주어야 함. 구성요소 메소드에 @Transactional 을 달아 주어 트랜잭션으로 관리 할 경우 rollback 이 정상적으로 작동하지 않는 경우가 발생함)

 

2. @Transactional 은 public 메소드에서만 정상 작동한다.

 

3. Spring Transaction은 기본적으로 unchecked Exception(런타임익셉션)만 관리하며 checked Exception(IOException, SQlExcption)등은 관리하지않는다. 

    처리방법 1) @Transactional(rollbackFor=Exception.class) 와 같이 설정하여

                        모든 Exception 발생시 rollback 이 발생하게 처리하는 방법

                    2) checked Exception 이 발생할 가능성이 있는 부분을 try ~ catch 로 처리하여

                        checked Exception 발생시 unchecked Exception 으로 예외를 바꾸어 던지게 처리)하여

                        Transaction의 관리대상으로 묶어서 처리하는 방법

 

@Transactional의 속성

Spring은 propagation 속성을 통해 Nested Transaction을 지정한다. Propagation(전파옵션) 종류를 보면

 

REQUIRED : 이미 시작된 트랜잭션(부모 트랜잭션)이 있으면 참여하고 없으면 새로 시작한다. (디폴트)
SUPPORTS : 이미 시작된 트랜잭션이 있으면 참여하고 없으면 트랜잭션 없이 진행한다.
REQUIRED_NEW : 부모 트랜잭션을 무시하고 항상 새로운 트랜잭션을 시작한다.
NESTED : 메인 트랜잭션 내부에 중첩된 트랜잭션을 시작한다. 부모 트랜잭션 결과에는 영향을 받지만, 자신의 트랜잭션 결과는 부모에게 영향을 미치지 않는다.
NOT_SUPPORTED : 트랜잭션을 사용하지 않게 한다. 이미 진행 중인 트랜잭션이 있으면 보류시킨다.
MANDATORY : REQUIRED와 비슷하게 이미 시작된 트랜잭션이 있으면 참여하지만, 트랜잭션이 시작된 것이 없으면 예외를 발생시킨다. (혼자서 독립적으로 트랜잭션을 진행하면 안되는 경우에 사용)
NEVER : 트랜잭션을 사용하지 않게 하며 이미 시작된 트랜잭션이 있으면 예외를 발생시킨다.
이러한 옵션을 설정하는 방법은 어노테이션 방식과 xml 방식이 있다.

어노테이션 방식 : @Transactional(propagation=Propagation.NESTED, rollbackFor=Exception.class)
xml 방식 : <tx:method name="insert*" propagation="NESTED" rollback-for="Exception" />

 

참고

https://deveric.tistory.com/86

 

[Spring] 트랜잭션의 전파 설정별 동작

트랜잭션의 전파 설정이란 Spring에서 사용하는 어노테이션 '@Transactional'은 해당 메서드를 하나의 트랜잭션 안에서 진행할 수 있도록 만들어주는 역할을 합니다. 이때 트랜잭션 내부에서 트랜잭

deveric.tistory.com

 

Comments