티스토리 뷰

반응형

트랜잭셔널 처리 전파 고립

JPA에서 @Transactional 어노테이션을 사용하다 보면 Propagation, Isolation과 관련된 이슈와 접할 때가 종종 있습니다. 오늘은 이런 내용들을 어떻게 사용하는지와 어떤 상황에서 사용하는지를 정리해보고자 합니다.

 

JPA Propagation 정리

세션의 트랜잭션을 어떻게 이용할지에 대한 설정입니다. 종류로는 아래와 같은 내용이 있습니다. 

종류 트랜잭션 존재시 트랜잭션 미존재시  비고
REQUIRED 기존 트랜잭션 이용 신규 트랜잭션 생성 기본설정이다
SUPPORTS 기존 트랜잭션 이용 트랜잭션 없이 수행  
MANDATORY 기존 트랜잭션 이용 Exception 발생 꼭 이전트랜잭션이 있어야 하는경우
NEVER exception이 발생한다 정상적으로 트랜잭션 없이 수행 트랜잭션 없을때만 작업이 진행되어야할때
NOT_SUPPORTED 트랜잭션이 종료될 때 까지 대기한 후 트랜잭션이 종료되고 나면 실행 트랜잭션 없이 로직이 수행 기존 트랜잭션에 영향을 주지 않아야할때 사용된다.
REQUIRES_NEW 현재 트랜잭션이 종료될 때 까지 대기한 후 새로운 트랜잭션을 생성하고 실행 신규 트랜잭션을 생성하고 로직을 실행 이전트래잭션과 구분하여 새로운 트랜잭션으로만 처리가 필요할때 사용
NESTED 현재 트랜잭션에 Save Point를 걸고 이후 트랜잭션을 수행 REQUIRED와 동일하게 신규 트랜잭션을 생성하고 로직이 수행 DBMS특성에 따라 지원 혹은 미지원

 

REQUIRED

  • @Transactional을 사용할 때 기본값입니다.
  • 트랜잭션 존재시: 기존 트랜잭션을 이용합니다.
  • 트랜잭션 미 존재시: 신규 트랜잭션을 생성합니다.
@Transactional(propagation = Propagation.REQUIRED)
public void writeData(Data data) {...}

// or

@Transactional
public void writeData(Data data) {...}

 

SUPPORTS

  • SUPPORTS는 현재 활성화된 트랜잭션이 있는지 검사합니다.
  • 트랜잭션 존재시: 기존 트랜잭션 이용합니다.
  • 트랜잭션 미 존재시: 트랜잭션 없이 수행합니다.
@Transactional(propagation = Propagation.SUPPORT)
public void writeData(Data data) {...}

 

MANDATORY

  • 트랜잭션이 필수적으로 필요한 propagation입니다.
  • 트랜잭션 존재시: 기존 트랜잭션을 이용합니다.
  • 트랜잭션 미 존재시: exception이 발생합니다.
@Transactional(propagation = Propagation.MANDATORY)
public void writeData(Data data) {...}

 

NEVER

  • 트랜잭션을 사용하지 않고, 있으면 에러를 던집니다.
  • 트랜잭션 존재시: exception이 발생합니다.
  • 트랜잭션 미 존재시: 정상적으로 수행됩니다. (즉, 트랜잭션 없이 수행한다.)
@Transactional(propagation = Propagation.NEVER)
public void writeData(Data data) {...}

 

NOT_SUPPORTED

  • 트랜잭션 존재시: 트랜잭션이 종료될 때까지 대기한 후 트랜잭션이 종료되고 나면 실행합니다.
  • 트랜잭션 미 존재시: 트랜잭션 없이 로직이 수행됩니다.
@Transaction(propagation = Propagation.NOT_SUPPORT)
public void writeData(Data data) {...}

 

REQUIRES_NEW

  • 트랜잭션 존재시: 현재 트랜잭션이 종료될 때까지 대기한 후 새로운 트랜잭션을 생성하고 실행합니다.
  • 트랜잭션 미 존재시: 신규 트랜잭션을 생성하고 로직을 실행합니다.
@Transaction(propagation = Propagation.REQUIRES_NEW)
public void writeData(Data data) {...}

 

NESTED

  • 이 옵션은, 데이터베이스가 지원하는지 여부와, JDBC 드라이버에서 지원해 주어야 동작합니다.
  • 트랜잭션 존재시: 현재 트랜잭션에 Save Point를 걸고 이후 트랜잭션을 수행합니다. (즉, 이후 트랜잭션 실패 시 Save Point까지 롤백되며, SAve Point이후는 트랜잭션 처리가 됩니다.)
  • 트랜잭션 미 존재시: REQUIRED와 동일하게 신규 트랜잭션을 생성하고, 로직이 수행됩니다.
@Transactional(propagation = Propagation.NESTED)
public void writeData(Data data) {...}

 


트랜잭션 처리

JPA Isolation 정리

Isolation Level은 동시 트랜잭션이 수행될 때 다른 트랜잭션이 동일한 데이터에 대해서 어떻게 보일지에 대해 범위를 나타냅니다. 

 

용어 

  • Dirty Read : 현재 트랜잭션에서 커밋되지 않은 변경 데이터를 다른 트랜잭션이 읽을 수 있는 권리입니다.
  • Nonrepeatable Read : 가장 먼저 데이터를 읽은 데이터가 다른 트랜잭션에서 변경을 한 다음, 다시 데이터를 읽을 때 변경된 데이터를 읽을 수 있음을 의미합니다.
  • Phantom Read : 다른 트랜잭션이 신규 데이터를 추가하거나 기존 데이터를 삭제할 때 범위 쿼리를 수행하면 데이터 Row가 달라지는 현상을 말합니다.

 

기본값

기본 Isolation은 DBMS에 설정한 Isolation level을 따라갑니다. 

  • Mysql : Repeatable Read 가 기본 설정입니다.
  • Oracle, SQL Server, Postgresql: READ_COMMIT이 기본 설정입니다.

 

종류

READ_UNCOMMITTED Isolation

  • 가장 느슨한 isolation level입니다.
  • 동시에 동일 데이터에 대해서 트랜잭션이 수행되는 경우 결과를 보장하지 못하고, 계속해서 커밋되지 않은 값을 읽을 수 있게 됩니다.
  • Dirty Read, Non-Repeatable Read, Phantom Read 현상이 모두 발생합니다.
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void writeData(Data data) {...}

 

READ_COMMITTED Isolation

  • Dirty Read가 발생하지 않습니다.
  • 하나의 트랜잭션에서 커밋이 수행된 데이터는 다시 읽기를 하면 변경된 데이터를 읽게 됩니다.
  • Non-Repeatable Read 현상과 Phantom Read 현상이 발생합니다.
@Transactional(isolation = Isolation.READ_COMMITTED)
public void writeData(Data data) {...}

 

REPEATABLE_READ Isolation

  • Dirty Read, Non-Repeatable Read 현상이 발생하지 않습니다.
  • 즉, 커밋되지 않는 데이터에 대해서 어떠한 사이드 이펙트가 없습니다.
  • 데이터를 다시 읽어도 원래 데이터를 그대로 유지하게 됩니다.
  • 그러나 범위 검색을 수행하는 경우 새로 추가된 데이터나, 삭제된 데이터가 보이게 됩니다.
  • 즉, Phantom Read현상이 발생합니다.
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void writeData(Data data) {...}

 

SERIALIZABLE Isolation

  • 이는 가장 엄격한 isolation level입니다.
  • 동시에 들어온 트랜잭션은 모두 serialize되어 순차적으로 수행되어야 하기 때문에 동시성에 관련된 사이드 이펙트는 없지만 성능이 매우 떨어지게 됩니다.
@Transactional(isolation = Isolation.SERIALIZABLE)
public void writeData(Data data) {...}

 


 

오늘은 JPA Transactional을 사용하면서 발생하는 전파방법(Propagation)과 DBMS에 따라 설정되는 Isolation에 대해 정리해보았습니다. JPA를 사용하는 경우 은근히 많이 사용되는 문법이고, 알고만 있어도 트랜잭션을 관리하는 서비스 레이어에서 보다 쉽게 적용할 수 있기 때문에 유용하게 사용하실 수 있을 것이라 생각하여 정리해보았습니다. 

출처: https://devocean.sk.com/blog/techBoardDetail.do?ID=163799 

 

면접 셤? 단골문제 JPA Propagation과 Isolation 이해하기

 

devocean.sk.com

 

반응형
댓글
공지사항