트랜잭션과 ACID
트랜잭션
트랜잭션 정의
- 데이터베이스의 상태를 변화시키는 작업 단위로, 전부 실행되거나 전부 실행되지 않는 '원자성'을 가짐
- 데이터베이스의 일관성과 무결성을 유지하기 위해 필수적인 조건
-
Commit : 여러 쿼리가 성공적을 처리되었음을 나타내는 명령어
-
Rollback: 트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌림
-
Spring에서는 @Transactional
어노테이션을 이용해 여러 쿼리 관련 코드들을 하나의 트랜잭션으로 처리
ACID 특징
트랜잭션은 원자성, 일관성, 격리성, 지속성의 특징을 가지고 이를 묶어 ACID 특징이라고 한다
특성 | 설명 |
---|
원자성 (Atomicity) | 트랜잭션이 데이터베이스에 모두 반영되거나 전혀 반영되지 않아야 함. All or Nothing |
일관성 (Consistency) | 트랜잭션이 성공적으로 완료되면, 데이터베이스가 일관된 상태를 유지해야 한다. 트랜잭션 전후로 데이터의 무결성이 지켜져야 함 |
격리성 (Isolation) | 힌 트랜잭션이 실행되는 동안 다른 트랜잭션의 간섭을 받지 않아야 한다 |
지속성 (Durability) | 한 트랜잭션이 성공적으로 완료되면 그 결과가 영구적으로 반영되어야 한다 |
무결성 보장을 위한 기능
- 체크섬: 데이터 전송 시 오류를 검출하는 방법
- 저널링: DB 변경 사항을 로그로 남겨 장애시 복구
- 무결성 제약 조건: 데이터의 정확성, 일관성 유지 위해 개체 무결성, 참조 무결성, 고유 무결성, Null 무결성 제약 조건 설정
트랜잭션의 격리 수준
격리수준 = 트랜잭션이 서로 격리되어 수행되는 정도. 데이터의 일관성과 동시성을 보장하기 위해 사용. 격리수준은 변경 가능
SERIALIZABLE
- 가장 높은 격리 수준으로 모든 트랜잭션이 순차적으로 진행
- 동시성은 낮아지지만, 트랜잭션 간섭으로 인한 이상 현상이 발생하지 않음
REPEATABLE READ
- 커밋된 데이터만 조회 트랜잭션 중에 조회한 행은 그 트랜잭션이 끝날 때까지 일정하게 유지되나 추가 행 삽입은 막을 수 없음 -> 팬텀 리드 현상 발생 가능
- MySQL 기본값
READ_COMMIT
- 커밋된 데이터에 대해서만 조회 가능. 대부분 RDBMS 기본값
- 팬텀리드와 반복 가능하지 않은 조회 발생 가능
READ_UNCOMMITED
- 가장 낮은 격리 수준
- 다른 트랜잭션이 커밋하지 않은 데이터도 읽을 수 있음
- 팬텀리드, 반복 가능하지 않은 조회, 더티 리드 발생 가능
격리 수준에 따른 이상 현상
팬텀 리드
- 유령처럼 데이터 행이 나타났다 사라지는 현상
- 한 트랜잭션 내에서 같은 쿼리를 2번 이상 수행했을 때 다른 결과가 나타나는 경우 (ex 새로운 행이 추가됨)
반복 가능하지 않은 조회
- 한 트랜잭션 내에서 같은 데이터 "행"을 2번 조회할 때 두 조회 결과가 다른 현상
더티 리드
- 한 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 데이터를 읽는 현상.
- 미완료 트랜잭션이 롤백시 더티리드한 트랜잭션은 잘못된 데이터를 기반으로 연산 수행
데드락
2개 이상의 트랜잭션이 서로의 잠금을 포기하기를 기다리는 상태 (무한 대기)
데드락의 해결 방법
교착상태 감지
- TimeOut: 일정 시간 동안 트랜잭션이 실행되지 않으면 자동 롤백
- 그래프 기반 사이클 탐색: 트랜잭션 간의 대기 그래프를 만들고, 그 안에서 사이클을 찾아 감지
- 비용의 문제로 잘 사용 X
교착 상태 방지
- 격리 수준 조정: 트랜잭션의 격리 수준을 조정하여 데드락의 발생 가능성을 줄임
- 서비스 로직 수정: 로직을 수정하여 트랜잭션들이 서로 교차하지 않도록 변경
wait-die와 wound-wait 방식
- wait-die: 오래된 트랜잭션이 잠금을 요구할 경우 대기, 새로운 트랜잭션이 요구할 경우 새로운 것을 종료시킴
- wound-wait: 오래된 트랜잭션이 요구시 새로운 것 일시 중단, 새로운 트랜잭션이 요구할 경우 대기
REF