Spring

@Transactional을 아시나요?

Flambee 2021. 3. 21. 01:23

 

@Transactional

Spring을 공부하다보면 AOP(Aspect oriented programming) 라는 주제가 항상 나온다. 그 AOP라는 주제에 대해서 공부하다보면 가장 먼저 나오는 AOP의 주제는 바로 @Transactional을 구현하는 것이다.

 

해당 @Transactional을 구현하는 방법에 대해서는 토비님의 책 중에 토비의 스프링Vol1에서 AOP의 주제와 함께 세세하게 설명되어 있다.

 

오늘은 바로 @Transactional이 무엇인지에 대해서 설명하려고 합니다.

 

@Transactional 이란?

우리가 알고있는 그 @Transactional

 

Spring에서 지원하는 트랜잭션 처리 Annotation.

 

 AOP로 구성되어 있으며, 직접적으로 Repository와 연결되어 작업되는 Service method에 @Transactional을 붙여주면, 처음에는 Begin, 끝에는 Commit을 붙여주면서, 하나의 Transaction을 도와주며, 만약에 에러가 발생할 시에 Rollback까지 해주는 Annotation입니다.

 

@Transactional은 Isolation, Propagation, ReadOnly 등을 설정할 수 있다.

ISOLATION(격리수준) : 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 하는 설정할 수 있다.
PROPAGATION(전파옵션) : 트랜잭션 도중 다른 트랜잭션을 호출해야하는 상황에 사용한다.
READONLY(읽기전용) : 트랜잭션을 읽기전용으로 만들 수 있다.
ROLLBACK(롤백 옵션) : 예외 클래스 설정. 
TIMEOUT(시간설정) : 시간 설정을 하여, 특정 시간내에 트랜잭션이 끝나지 않으면 롤백.

Isolation(격리수준)

- DEFAULT : 

기본격리수준.

 DB별 기본 격리수준.

MariaDB, Mysql : REPEATABLE READ

Oracle : READ_COMMITED

MSSQL : READ_COMMITED

MongoDB : READ_UNCOMMITED

postgresql : READ_UNCOMMITED

 

- READ_UNCOMMITED(LEVEL0) :

다른 트랜잭션이 관여할 수 있다.

커밋이 되지 않은 부분까지 읽기 허용.

롤백이 될 데이터까지 불러옴.

LOCK이 발생하지 않음.

* MSSQL의 NOLOCK의 기능을 전체적으로 해주는 것이 바로 READ_UNCOMMITED이다.

 

- READ_COMMITED(LEVEL1) :

다른 트랜잭션이 관여할 수 있다.

커밋이 된 부분만 읽기 허용.

많은 양의 데이터를 복제하거나 이동할 때 추천.

 

- REPEATETABLE_READ(LEVEL2) :

하나의 트랜잭션에서 하나의 스냅샷만 사용. 

데이터 조회 시 항상 동일한 데이터 응답을 보장.

동일 트랜잭션 상에서 일관성을 보장한다.

* JPA의 1차캐시로 인한 영속성 읽기는 REPEATETABLE_READ를 사용한다.

 

- SERIALIZABLE(LEVEL3) :

Read시에 DML 관련 작업이 불가능.

 

Propagation(전파옵션)

- REQUERIED(DEFAULT) : 부모 트랜잭션 내에서 사용하며, 부모 트랜잭션이 없을 때 새로운 트랜잭션 사용.

- REQUERIES_NEW : 무조건 새로운 트랜잭션 사용.

- SUPPORT :  부모 트랜잭션 내에서 사용하며, 부모 트랜잭션이 없을 경우 nontransactional처리가 된다.

- NOTSUPPORT : nontransactional처리가 되며 부모 트랜잭션에서 사용되면 일시정지 됩니다.

 (메소드 실행 시 트랜잭션 없이 실행 됨. 트랜잭션 자체가 없기 때문에 Flush가 호출되지 않음. ReadOnly = true 효과.)

- MANDATORY : 부모 트랜잭션 내에서 사용되며, 부모 트랜잭션이 없으면 예외가 발생한다.

- NEVER : nontransactionally처리가 되며 부모 트랜잭션에서 사용되면 예외가 발생한다.

- NESTED : 해당 메서드가 부모 트랜잭션 내에서 사용되면 별개로 커밋되거나 롤백될 수 있으며, 부모 트랜잭션이 없으면 새로운 트랜잭션 사용.

 

READONLY(읽기전용)

- 트랜잭션을 읽기전용으로 만들어준다.

- 성능 최적화 용으로 많이 사용됨.

( Hibernate의 Session Flush가 MANUAL 설정이 되어 트랜잭션 커밋 시 자동으로 Flush하지 않기 때문.)

* MSSQL의 NOLOCK효과(커밋이 되지 않은 부분까지 읽기 허용)을 사용하려면 READ_ONLY + Isolation Level(Uncommitted_Read)를 사용하면 된다.

 

ROLLBACK(롤백옵션)

- ROLLBACK_FOR : 특정 예외가 발생했을 때 롤백 처리.

- NO_ROLLBACK_FOR : 특정 예외 발생 시 롤백처리가 되지 않음.

 

TIMEOUT(시간옵션)

- 시간 설정을 하여, 특정 시간내에 트랜잭션이 끝나지 않으면 롤백.

 


여기까지가 바로 @Transactional의 기본적인 내용이다.

 

다음에는 @Transactional 사용 시 주의점에 대해서 포스팅하겠습니다.

 

저는 그럼 요가하러 가볼게요~ 춍춍