본문 바로가기
Java | spring/Spring

스프링 트랜잭션 @Transactional 개념 (+주요 설정값)

by 워니 wony 2021. 6. 4.

스프링에서 트랜잭션을 사용하는 @Transaction 어노테이션을 추가 하게 된다. 일반적으로 DB에서 데이터를 조회, 추가, 수정, 삭제 등을 하는 경우 메소드 상단에 트랜잭션 어노테이션을 붙인다. 보통은 그정도로만 사용해서 상세하게 트랜잭션에 대해 공부해야 한다는 생각을 하지 않는다.

 

실무에서도 프로젝트에서도 일반적으로 트랜잭션 설정값을 거의 안쓰거나, 보통은 설정값으로 readOnly 정도만 사용하는 경우가 많다. 하지만 대용량 동기화, 배치 등을 진행 할때 트랜잭션 관련 설정을 하게 되는 경우가 있다. 그럼 관련된 설정이나 설명을 봐도 명확하게 이해가 되지 않기도 한다. 또한, 개발자 기술 면접에서도 아래와 같이 질문 하는 경우도 다수 있다. 나도 면접 시에 답변을 한 적이 몇번 있다.

 

 트랜잭션 사용해 봤나요?
어떤 식으로 사용했나요?
문제가 있는 경우 어떻게 해결했나요?
dirty read 상태가 뭔지 설명해 보세요.
 


복잡한 프로젝트를 하더라도 개념이나 설정에 대해 알고 있으면 문제가 발생해도 어떻게 처리할지 아이디어가 생길수도 있다. 또한 개발자 기술 면접을 준비하고 있다면 제대로 답변할 수 있도록 체계적으로 개념 정리해 보는 시간을 가져보자.

 

스프링을 이용한 트랜잭션 관리

  • 스프링 프레임워크는 프로그래밍 방식 선언식 트랜잭션 관리를 모두 지원
  • 스프링의 트랜잭션 관리 추상화를 사용해 명시적으로 트랜잭션을 시작, 종료, 커밋
  • 스프링에서 단일 트랜잭션 내에서 실행할 메서드에 스프링의 @Transaction 어노테이션을 지정하면 선언식 트랜잭션 관리를 사용할 있음

 

프로그래밍 방식의 트랜잭션 관리

  • 프로그래밍 방식으로 트랜잭션을 관리하려면 스프링의 TransactionTemplate 클래스를 사용하거나 스프링 PlatformTransactionManager 인터페이스 사용
  • TransactionTemplate 클래스는 트랜잭션의 시작 커밋을 담당해서 트랜잭션 관리를 간소화
  • 개발자는 단일 트랜잭션 내에서 실행될 코드를 포함하는 스프링 TransactionCallback 인터페이스 구현

 

 

선언식 트랜잭션 관리 @Transactional

  • 메서드나 클래스에 스프링의 @Transactional 어노테이션을 지정하면
  • 특정 메서드에 지정하면 해당 메서드가 단일 트랜잭션 내에서 실행되며, 특정 클래스에 지정하면 해당 클래스의 모든 메서드를 단일 트랜잭션 내에서 실행하게 됨
  • 메서드에 @Transactional 어노테이션 작성 시, 해당 메서드 실행 java.lang.RuntimeException 발생하면 트랜잭션이 롤백

 

 

 

@Transactional 설정값

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 걸리므로 다른 사용자는 영역에 해당되는 데이터에 대한 수정 입력이 불가능

 

propagaion : 전파옵션

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

 

주요 설정

readOnly

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

 

rollbackFor

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

 

no-rollback-for-예외처리

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

 

timeout

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

댓글