Forest Gump?

@Transactionial 이란? (스프링 트랜잭션 어노테이션) 본문

카테고리 없음

@Transactionial 이란? (스프링 트랜잭션 어노테이션)

code1010 2022. 1. 3. 18:03

트랜잭션이란 스프링에서 어노테이션으로 쓰이는 처리 방식으로, @Transactional 마크를 붙여서 사용한다.

그럼 어떤경우에 사용하는지 알아보자. 

 

실무에서 쓰면서 생각보다 간단히 이해한 방법이 있다. 어릴적 했던 포켓몬에서 사천왕을 깰때, 세이브 해놓고 몇번이고 들어가서 때려잡았던 기억을 떠올리면 된다. 모든 작업이 성공적으로 완료되어야지만, 이제 정상적으로 진행이 되고 

만약 4천왕 묵호까지만 잡고 레드를 못잡았을때는 아쉽지만 다시 세이브 해놓은 파일로 시간을 돌릴수가 있는것이다. 

물론 생각보다 이렇게 간단한 작업은 아니긴 하지만 (언제나 그렇듯 Auto Increment 등 되돌릴 수 없는 예외도 있다) ,

이렇게 생각하는게 도움이 되었다. 

 

DB를 사용할떄, 트랜잭션 어노테이션을 적용하며 데이트 INSERT,UPDATE,DELETE등으로 이루어진 DML( Data Manipulation Language) 처리중 오류가 발생할때, 모든 작업들을 원상태로 되돌릴 수 있다. 

모든 작업이 완료 되어야지만 정상적으로 DB에 반영하도록 하는것이다. 

 

간단히 Transactional annotation에 대해 알아봤으므로, 이제 옵션들을 간략히 살펴 보고자 한다.

 

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class },isolation = Isolation.READ_COMMITTED)
public class DBService {

이런식으로 사용되는데, 각각의 옵션은 다음과 같다.

 

 

propagation : 전파옵션

  • REQUIRED : 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 새로운 트랜잭션을 생성
  • REQUIRES_NEW : 부모 트랜잭션을 무시하고 무조건 새로운 트랜잭션이 생성
  • SUPPORT : 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 nontransactionally로 실행
  • MANDATORY : 부모 트랜잭션 내에서 실행되며 부모 트랜잭션이 없을 경우 예외가 발생
  • NOT_SUPPORT : nontransactionally로 실행하며 부모 트랜잭션 내에서 실행될 경우 일시 정지
  • NEVER : nontransactionally로 실행되며 부모 트랜잭션이 존재한다면 예외가 발생
  • NESTED : 해당 메서드가 부모 트랜잭션에서 진행될 경우 별개로 커밋되거나 롤백될 수 있음. 둘러싼 트랜잭션이 없을 경우 REQUIRED와 동일하게 작동

 

isolation : 트랜잭션 격리 수준을 지정

  • READ_UNCOMMITTED(level 0) : 트랜잭션 처리중인 혹은 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용
    • Dirty read : 다른 트랜잭션에서 처리하는 작업이 완료되지 않았는데도 다른 트랜잭션에서   있는 현상, 해당 수준에서만 일어나는 현상
  • READ_COMMITTED(level 1) : dirty read 방지(확정된 데이터만 읽는  허용), 데이터를 변경하는 동안 다른 사용자는 해당 데이터에 접근 불가
  • REPEATABLE_READ(level 2) : 트랜잭션이 완료   까지 select 문장이 사용하는 모든 데이터에 shared lock 걸리므로 다른 사용자는  영역에 해당 되는 데이터에 대한 수정이 불가능, 트랜잰션 종료까지 갱신, 갱신 삭제가 불허되어 일관성 있는 결과를 리턴함
  • SERIALIZABLE(level 3) : 완벽한 읽기 일관성 모드 제공, 데이터 일관성  동시성을 위해 MVCC 사용하지 않음, 트랜잭션이 완료  때까지 select 문장이 사용하는 모든 데이터에 shared lock 걸리므로 다른 사용자는  영역에 해당되는 데이터에 대한 수정  입력이 불가능

readOnly : 읽기전용

  • 해당 트랜잭션을 읽기전용으로 하는 경우 사용
  • 데이터를 조회하는 select 관련 메서드의 경우 해당 설정 사용
  • @Transactional(readOnly = true)

 

rollbackFor : 예외 클래스 지정

  • 롤백을 유발하는 예외 클래스를 지정
  • @Transactional(rollbackFor=Exception.class)

 

no-rollback-for-예외처리

  • 기본값 없음
  • 특정 예외가 발생하더라도 롤백되지 않도록 설정
  • @Transactional(noRollbackFor=Exception.class)

 

timeout : 타임지정 롤백

  • 지정한 시간내에 메소드가 실행되지 않은 경우 롤백하는 설정
  • 숫자를 -1 쓰면 지정된 시간이 없음(default)
  • @Transactional(timeout=5)

이중 나는 protagation의 REQUIRED, REQUIRES_NEW , 또 (rollbackFor=Exception.class) 혹은 (readOnly = true)를 많이 쓴거 같다.

 

Protagation의 예외처리는 상황에 따라서 너무 다양하고 복잡하므로, 좀 더 배워서 다른글에서 기술해보도록 하겠다.