@Transactional이란
스프링에서 트랜잭션처리하는 방법 중 하나로, 어노테이션을 활용한 선언적 트랜잭션이라 한다.
여기서 트랜잭션이란 DB의 값을 변경하는 일련의 작업들을 하나의 처리로 묶어 반영(Commit)시키거나 취소(RollBack)시키는 것을 의미한다.
트랜잭션 옵션
1. isolation (격리레벨)
- 트랜잭션에서 일관성 없는 데이터 허용 수준을 설정한다.
적용방법
@Transactional(isolation=Isolation.DEFAULT)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
- DEFAULT : 기본 격리 수준
= 기본이며, DB의 Isolation Level을 따른다. - READ_UNCOMMITED (level 0) : 커밋되지 않는 데이터에 대한 읽기를 허용
= 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은 (Uncommitted 혹은 Dirty)데이터 B를 읽을 수 있다.
-Problem1 - Dirty Read 발생 - READ_COMMITED (level 1) : 커밋된 데이터에 대해 읽기 허용
= 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없다.
-Problem1 - Dirty Read 방지 - REPEATABLE_READ (level 2) : 동일 필드에 대해 다중 접근 시 모두 동일한 결과를 보장
= 트랜잭션이 완료 될 때 까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다.
= 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제가 불가능 하기 때문에 같은 데이터를 두 번 쿼리했을 때 일관성있는 결과를 리턴한다.
-Problem2 - Non-Repeatable Read 방지 - SERIALIZABLE (level 3) : 가장 높은 격리, 성능 저하의 우려가 있음
= 데이터의 일관성 및 동시성을 위해 MVCC(Multi Version Concurrency Control)을 사용하지 않음.
(MVCC는 다중 사용자 데이터베이스 성능을 위한 기술로 데이터 조회 시 LOCK을 사용하지 않고 데이터의 버전을 관리해 데이터의 일관성 및 동시성을 높이는 기술)
= 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능하다.
-Problem3 - Phantom Read 방지
2. propagation (전파속성)
- 트랜잭션 동작 도중 다른 트랜잭션을 호출할 때, 어떻게 할 것인지 지정하는 옵션이다.
적용방법
@Transactional(propagation=Propagation.REQUIRED)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
- REQUIRED (Default)
이미 진행중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 진행중이 아니라면 새로운 트랜잭션을 생성한다. - REQUIRES_NEW
항상 새로운 트랜잭션을 생성한다. 이미 진행중인 트랜잭션이 있다면 잠깐 보류하고 해당 트랜잭션 작업을 먼저 진행한다. - SUPPORT
이미 진행중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 없다면 트랜잭션을 설정하지 않는다. - NOT_SUPPORT
이미 진행중인 트랜잭션이 있다면 보류하고, 트랜잭션 없이 작업을 수행한다. - MANDATORY
이미 진행중인 트랜잭션이 있어야만 작업을 수행한다. 없다면 Exception을 발생시킨다. - NEVER
트랜잭션이 진행중이지 않을 때 작업을 수행한다. 트랜잭션이 있다면 Exception을 발생시킨다. - NESTED
진행중인 트랜잭션이 있다면 중첩된 트랜잭션이 실행되며, 존재하지 않으면 REQUIRED와 동일하게 실행된다.
3. noRollbackFor (예외무시)
- 특정 예외 발생 시 rollback하지 않는다.
적용방법
@Transactional(noRollbackFor=Exception.class)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
4. rollbackFor (예외추가)
- 특정 예외 발생 시 rollback한다.
적용방법
@Transactional(rollbackFor=Exception.class)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
5. timeout (시간지정)
- 지정한 시간 내에 메소드 수행이 완료되지 않으면 rollback 한다. (-1일 경우 timeout을 사용하지 않는다.)
default = -1
적용방법
@Transactional(timeout=10)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
6. readOnly (읽기전용)
- 트랜잭션을 읽기 전용으로 설정한다.
default = false,
true시 insert, update, delete 실행 시 예외 발생
적용방법
@Transactional(readonly = true)
public void addUser(UserDTO dto) throws Exception {
// 로직 구현
}
'프로그래밍 > Spring' 카테고리의 다른 글
[Spring] (SpringBoot) SQL 로그 남기기 (0) | 2022.03.29 |
---|---|
[Spring] log4j (0) | 2022.03.28 |
[Spring] SpringSecurity 비밀번호 암호화 (0) | 2022.03.15 |
[Spring] 싱글톤 패턴(Singleton pattern) (0) | 2022.03.11 |
[Spring] 의존성주입(Dependency Injection, DI) (0) | 2022.03.11 |