트랜잭션 이란?
트랜잭션이란 더 이상 쪼갤 수 없는 최소 단위의 작업을 뜻하는 개념으로, 트랜잭션 경계 안에서 진행된 작업은 commit()을 통해 모두 성공하던지, 아니면 rollback()을 통해 모두 취소돼야 함
전파 옵션 (propagation)
보통 하나의 메서드에서 하나의 트랜잭션을 사용하는데, 하나의 메서드에서 여러가지 트랜잭션을 사용할 경우 어떻게 처리할지 결정하는 옵션이다.
- REQUIRED : 부모 트랜잭션 내에서 실행하고 만약 부모 트랜잭션이 없을 경우 새로운 트랜잭션을 생성한다
- REQUIRES_NEW : 부모 트랜잭션을 무시하고 무조건 새로운 트랜잭션을 생성
- SUPPORT : 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 nontransactionally로 실행한다
- MANDATORY: 부모 트랜잭션 내에서 실행되며 부모 트랜잭션이 없을 경우 예외가 발생한다
- NOT_SUPPORT: nontransactionally로 실행하며 부모 트랜잭션 내에서 실행될 경우 일시정지
- NEVER : nontransactionally로 실행되며 부모 트랜잭션이 존재한다면 예외가 발생
- NESTED: 해당 메서드가 부모 트랜잭션에서 진행될 경우 별개로 커밋되거나 롤백될 수 있으며 둘러싼 트랜잭션이 없을 경우 REQUIRED와 동일하게 작동한다
격리수준 (isolation)
일관성이 없는 데이터를 허용하도록 하는 수준
- LEVEL 0 - READ_UNCOMMITED
- 트랜잭션 중에 처리중이거나 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용
- 트랜잭션 작업이 완료되지 않았는데 다른 트랜잭션에서 커밋전 정보를 볼 수 있게 되는 dirty read 현상 발생
ex) 1. A 트랜잭션에서 할인가 20퍼에서 -> 30퍼로 수정 (아직 커밋 전)
2. B 트랜잭션에서 할인가를 조회하면 30퍼로 읽어와진다 (dirty read)
3. 30퍼는 할인가가 거서 rollback해서 20퍼로 수정
4. 하지만 B 트랜잭션에서는 할인가 30퍼로 로직이 수행 -> 데이터 정합성 문제 발생
- LEVEL 1 - READ_COMMITED
- dirty read 방지 : 트랜잭션이 커밋되어 확정된 것만 읽는 걸 허용
- RDBMS 에서 기본적으로 사용하고 있는 방식 (mysql 에선 repretabled_read 사용)
ex) 1. A 트랜잭션에서 할인가 20퍼에서 -> 30퍼로 수정 (아직 커밋 전)
2. B 트랜잭션에서 할인가 조회시 20퍼로 조회(undo 영역의 백업된 레코드에서 값을 가져오기 때문)
3. A 트랜잭션이 커밋 진행 ( 20 -> 30 )
4. B 트랜잭션에서 다시 할인가 조회하면 30으로 바뀌어 있다
-> 하나의 트랜잭션 내에서 똑같은 select 수행시 항상 동일한 결과를 반환하는 repeatable_read 정합성 오류
- LEVEL 2 - REPRETABLE_READ
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회 가능
- 트랜잭션이 완료될 때까지 select하는 모든 데이터에 shared lock이 걸림
- shared loack 영역에서 수정이 불가능(선행 트랜잭션이 읽는 데이터를 후행 트랜잭션이 수행할 수 없음)
- 여기에서는 다른 트랜잭션이 수행한 변경작업에 의한 레코드가 보였다 안보였다하는 phantom read 현상이 일어날 가능성-> 쓰기 잠금을 걸어서 해결
- LEVEL 3 - SERIALIZABLE
- 완벽하게 읽기 일관성 모드를 제공한다 (모든 작업에 shared lock)
- phantom read 방지
- 동시 처리 성능이 가장 낮아 거의 사용되지 않는다
참고
'Spring > about spring' 카테고리의 다른 글
[IoC 컨테이너와 빈] @Autowired (0) | 2023.07.22 |
---|---|
[IoC 컨테이너와 빈] ApplicationContext (0) | 2023.07.19 |
[스프링 삼각형] PSA 잘 만든 인터페이스 (0) | 2023.07.17 |
[스프링 삼각형] AOP 관점 지향 프로그래밍 (0) | 2023.07.11 |
[스프링 삼각형] Inversion of Control 제어의 역전 (0) | 2023.07.11 |