본문 바로가기

[Kotlin&Spring] 5기 내일배움캠프

[Kotlin&Spring] 5기 개인과제 트러블슈팅 - 트랜잭션 전파

트랜잭션(Transaction)이란

데이터베이스의 상태를 변화시키기 위한 작업의 단위를 말한다

 

스프링부트에서 지원하는 트랜잭션 어노테이션 인터페이스는 다음과 같다

@Transactional 은 타입(클래스 전체), 메소드에 적용 가능하다

또한 적용되는 범위 정책이 런타임 시점임을 알 수 있다

 

 

@Transactional은 다양한 속성값(value)을 가지고있다 그 중 자주 사용되는 트랜잭션의 속성을 설명하고자 한다

 

1. 트랜잭션 전파(transaction propagation)
트랜잭션의 경계에서 이미 진행 중인 트랜잭션이 있을 때의 동작 방식을 정의한다

독자적인 트랜잭션 단위가 될 수도 있고, 다른 트랜잭션의 일부로 참여할 수도 있다

Propagation_REQUIRED
진행 중인 트랜잭션이 없으면 새로 시작한다
이미 시작된 트랜잭션이 있으면 이에 참여한다

Propagation_REQUIRES_NEW
진행 중인 트랜잭션의 유무와 관계 없이 항상 새로운 트랜잭션을 시작한다

Propagation_NOT_SUPPORTED
진행 중인 트랜잭션의 유무와 관계 없이 트랜잭션 없이 동작한다
모든 메소드에 트랜잭션 AOP를 적용한다
특정 메소드의 트랜잭션 속성만 해당 속성을 적용한다

 

스프링 프레임워크의 트랜잭션 전파 enum

 

위 3개의 enum값 말고도 전파 속성에는  다양한 값이 존재한다

이는 각각의 메소드에 트랜잭션을 부여하는 것보다 공통적으로 트랜잭션 속성을 부여하고 특정 트랜잭션에만 속성값을 달리 할 수 있음을 보여준다

 

아래 이미지는 과제 중 trasaction 전파에 대해 찾아보게 된 이유이다

매니져 등록과 그에 대한 로그가 다른 트랜잭션에서 실행되어야 했다

따라서 나는 로그 생성 메소드에 다른 트랜잭션이 항상 실행되는 Propagation.REQUIRES_NEW 속성 값을 사용했다  

로그 생성 메소드

 

또한 메니져 등록에 있어서는 매니져 객체를 생성 후 저장하는 로직이 있기 때문에

@Transactional 을 사용하여 default 값인 Propagation.REQUIRED 속성을 사용했다

매니져 등록 메소드

 

try-catch문을 사용한 이유는 예외처리에 대해서도 로그를 작성하고 예외를 일으켜 클라이언트에 오류 메세지를 보내기 위함이다

 

로그 엔티티 클래스

 

예외 상황에도 로그객체는 만들어져야하기 때문에 엔티티 필수 정보인 로그 ID 를 제외하고 속성을 nullable 로 설정했다

 

트랜잭션 전파 속성 외에도 @Transactional 의 속성값의 의미를 알고 싶어 간단히 정리해봤다


2. 격리 수준(isolation level)
가능한 한 많은 트랜잭션을 동시에 진행하면서 문제가 발생하지 않게 하는 제어를 위한 속성이다

 

1) READ UNCOMMITTED: 커밋되지 않은 읽기

- 커밋하지 않은 데이터를 읽을 수 있다(DIRTY READ)

트랜잭션 여러 개가 하나의 자원에 접근 -> 수정중인 데이터를 조회할 수 있다

 

2) READ COMMITTED: 커밋된 읽기

NON-REPEATABLE READ가 발생할 수 있다

일관적인 데이터 읽기가 불가능하다

 

3) REPEATABLE READ: 반복 가능한 읽기

반복 데이터 조회 시 결과 집합이 달라지는 PHANTOM READ가 발생할 수 있다

 

4) SERIALIZABLE: 직렬화 가능

동시성 처리 성능이 급격히 떨어진다


3. 제한 시간(timeout)
트랜잭션을 수행하는 제한시간 설정

데이터베이스 종류에 따라 작동하지 않을 수 있다

4. 읽기 전용(read only)
트랜잭션 내에서 데이터를 조작하는 시도를 막는다

 

이번 과제를 하며 스스로에게 부족한 점을 많이 느낀다

어떻게든 이겨내고 앞으로 성장하는 내가 되었으면 한다