Transaction이란?
Transaction이란 데이터의 상태를 변화시키기 위한 작업들의 집합 단위이다.
Spring에서 @Transactional의 동작과정
@Transaction이 적용되어 있을 경우 해당 클래스에 대한 트랜잭션 기능이 적용된 프록시 객체가 생성된다.
이 프록시 객체는 @Transactional이 포함된 해당 메서드가 호출될 경우 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback을 수행한다.
정상여부는 default로 RuntimeException이 발생했는지 안했는지의 기준으로 결정된다.
Transaction의 특징
Transaction은 ACID라고 불리는4가지의 특징이 있는데
- 원자성 (Atomicity) : 트랜잭션이 데이터베이스에 모두 반영되던가, 아니면 전혀 반영되지 않아야 한다는 것
- 일관성 (Consistency) : 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것
트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트된 데이터베이스로 트랜잭션이 진행되는것이 아니라, 처음에 트랜잭션을 진행 하기 위해 참조한 데이터베이스로 진행된다. 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것이다 - 독립성 (Isolation) : 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다는 점을 가리킨다 하나의 특정 트랜잭션이 완료될때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다
- 지속성 (Durability) : 트랜잭션이 성공적으로 완료됬을 경우, 결과는 영구적으로 반영되어야 한다는 점
이 4가지 특징은 Transaction이 가져야 할 성질들이지만, 너무 이 특징들이 잘 지켜졌을 경우에는 문제점이 발생할 수 있다.
특히 독립성 (Isolation) 부분에서 동시성 문제가 발생하는데,
Transaction 동시성문제
- Dirty Read : 트랜잭션이 커밋되지 않았는데도 다른 트랜잭션에서 커밋되지 않은 데이터를 읽는 현상
- Non-repetable Read : 한 트랜잭션 내의 SELECT 결과가 다르게 읽히는 현상 (선행 트랜잭션에서 첫번째로 수행한 SELECT와 두번째로 수행한 SELECT 결과가 다르게 읽히는 현상, 후행 트랜잭션에서 해당 데이터를 수정 또는 삭제할 때 나타나는 현상)
- Phantom Read : 한 트랜잭션 내에서 같은 쿼리를 두 번 실행했을 경우, 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상을 말한다. (후행 트랜잭션에서 선행 트랜잭션에서 조회한 조건과 일치하는 데이터를 추가했을 경우 나타나는 현상)
여기서 Non-repetable Read 와 Phantom Read가 헷갈릴 수 있는데,
Phantom Read 는 기존 조회결과에 없던 것이 생겨나거나 없어지는 현상을 의미하고
Non-repetable Read 는 기존 조회결과와 다른 결과값이 반환된다는 의미이다.
이 문제들을 해결하기 위해 Spring에서는 @Transactional에 isolation이라는 옵션을 추가해놨다.
이어서 @Transactional의 옵션 2가지에 대해 알아보겠다.
Spring @Transactional의 옵션 : propagation, isolation
1. propagation
- 특정 트랜잭션 동작 도중 또다른 트랜잭션을 호출(실행) 하는 상황에서 트랜잭션을 어떻게 동작시킬 것인지 결정하는 방식 (ex. 트랜잭션이 적용된 메서드에서 트랜잭션이 적용된 또다른 메서드를 호출하는 상황)
- 호출 당한 트랜잭션 입장에서 호출한 쪽의 트랜잭션을 그대로 사용할 수도 있고, 새롭게 트랜잭션을 생성할 수도 있음
- 이러한 트랜잭션 관련 설정은 @Transactional의 propagation 속성을 통해 지정가능
2. isolation
- Isolation Level은 동시 트랜잭션이 수행될때 다른 트랜잭션이 동일한 데이터에 대해서 어떻게 보일지에 대한 범위를 나타낸다.
- Transaction의 동시성 문제를 해결하기 위한 옵션
@Transactional의 isolation 옵션은 트랜잭션의 격리 수준을 지정하는 옵션으로
isolation의 격리 수준을 높힐 경우 데이터의 일관성은 향상될 수 있으나, 성능의 저하가 일어난다.
왜냐하면 하나의 트랜잭션이 수행 중 일때 격리 수준이 높을 수록 다른 트랜잭션을 수행하는데 제약이 있을 수 있기 때문이다.
'백엔드 멘토링' 카테고리의 다른 글
단축 url 서비스 Base62으로 리팩터링하기 - 회고록 (1) | 2023.10.08 |
---|---|
자바의 신 - 복습 정리(2) (0) | 2023.09.23 |
2023-08-29 DB 관련 질문 정리 (0) | 2023.08.30 |
객체지향의 사실과 오해 후기 (0) | 2023.08.27 |
자바의 신 - 복습 정리(1) (0) | 2023.08.27 |