[데이터베이스] 트랜잭션
Updated: Categories: CS트랜잭션에 대해 알아보자
트랜잭션
- 데이터베이스의 상태를 변화시키키기 위해 수행하는 작업의 단위
- 한꺼번에 수행되어야 할 일련의 작업
- 하나의 트랜잭션은 커밋되거나 롤백된다
Commit
: 트랜잭션 결과를 DB에 반영Rollback
: 오류가 한번이라도 났을 경우 해당 트랜잭션 종료 or 재시작
특징
- 원자성 (Atomicity)
- 트랜잭션내 작업은 모두 반영되거나 모두 반영되지 않아야 한다.
- 트랜잭션 내 작업 중 하나라도 오류 발생시 트랜잭션 전부가 취소되어야 한다
- 일관성 (Consistency)
- 트랜잭션 결과 데이터베이스는 언제나 일관성 있는 상태여야 한다.
- 트랜잭션 도중 수정된 상태를 참조하지 않고, 수정 전 상태를 참조함
- 독립성 (Isolation)
- 둘 이상의 트랜잭션이 동시 실행되는 경우 서로의 연산에 끼어들 수 없다
- 수행중인 트랜잭션은 완전히 완료될때까지 다른 트랜잭션의 결과를 참조할 수 없다.
- 영속성 (Durablility)
- 성공적으로 완료된 트랜잭션 결과는 영구적으로 반영되어야 한다.
트랜잭션 격리수준
- 여러 트랜잭션이 동시실행될 때 트랜잭션끼리 얼마나 고립되어 있는지를 나타내는 것
- 일관성과 독립성을 위반하는 수준
문제상황
- dirty reads
- 트랜잭션 실행 후 변경된 모든 데이터가 반영되는 현상
- 사용자의 나이를 두번 조회하는 트랜잭션
T1
실행 -> 처음 나이 : 20 T1
- 첫번째 조회쿼리 실행 -> 조회된 나이 : 20T2
- 데이터 수정 -> 변경된 나이 : 21T1
- 두번째 조회쿼리 실행 -> 조회된 나이 : 21
- 사용자의 나이를 두번 조회하는 트랜잭션
- 트랜잭션 실행 후 변경된 모든 데이터가 반영되는 현상
- non-repeatable reads
- 트랜잭션 실행 후 수정 + 커밋된 데이터까지 반영되는 현상
- 사용자의 나이를 두번 조회하는 트랜잭션
T1
실행 -> 처음 나이 : 20 T1
- 첫번째 조회쿼리 실행 -> 조회된 나이 : 20T2
- 데이터 수정 + 커밋 -> 변경된 나이 : 21T1
- 두번째 조회쿼리 실행 -> 조회된 나이 : 21
- 사용자의 나이를 두번 조회하는 트랜잭션
- 트랜잭션 실행 후 수정 + 커밋된 데이터까지 반영되는 현상
- phantom reads
- 트랜잭션 실행 후 추가 + 커밋된 유령 데이터까지 반영되는 현상
- 모든 사용자 수를 두번 조회하는 트랜잭션
T1
실행 -> 총 사용자 3명 T1
- 첫번째 조회쿼리 실행 -> 총 사용자 3명T2
- 사용자 1명 추가 후 커밋 -> 총 사용자 4명T1
- 두번째 조회쿼리 실행 -> 총 사용자 4명
- 모든 사용자 수를 두번 조회하는 트랜잭션
- 트랜잭션 실행 후 추가 + 커밋된 유령 데이터까지 반영되는 현상
격리수준
- READ_UNCOMMITTED
- 제한없이 모든 데이터 조회
- 표준도 아님
- READ_COMMITTED
- 커밋 완료된 데이터만 조회
- 온라인서비스에서 가장 많이 선택됨
- REPEATABLE_READ
- 트랜잭션이 시작되기 전 커밋된 데이터만 조회
- MySQL default
- SERIALIZABLE
- 트랜잭션 종료시까지 공유잠금
- 동시처리 능력이 매우 낮아서 실제 사용 X
Lock
- 트랜잭션의 순차성을 보장하기 위한 방법
- DB, 테이블, 행 단위로 Lock을 걸수 있으며, 보통 행 단위로 사용함
종류
- 공유 락
- Shared/Read Lock
- 읽기 연산만 허용하고 쓰기 연산은 허용하지 않음
- 한 데이터에 여러개의 공유락이 동시에 걸릴 수 있지만, 배타락은 걸 수 없음
- 배타 락
- Exclusive/Write Lock
- 읽기/쓰기 연산 모두 금지
- 한 데이터에 배타락 하나만 걸 수 있음
Blocking
- 특정 데이터에 배타 락이 걸려있을 경우 해당 트랜잭션이 완료되기 전까지 해당 데이터 관련 작업이 모두 중단되는 현상
- 블로킹은 성능 저하를 불러오므로 최소화해야함
DeadLock
- 두 트랜잭션이 각각 데이터에 Lock을 걸어놓아 두 트랜잭션 모두 영원히 작업을 끝내지 못하는 현상
- 교착상태 발생시 DBMS가 한 트랜잭션에 에러를 발생시켜 문제를 해결함
- 해결법
- 트랜잭션 내 작업 최소화
- 트랜잭션간 데이터 교차 접근 최소화
- 데이터 잠금 최소화
Lock 전략
- 데이터에 동시 접근하는 상황일 경우, 충돌이 발생하는데 이를 Lock 전략을 통해 해결 가능
비관적 락
REPEATABLE_READ
이상의 격리 수준에서 사용가능- 트랜잭션이 시작될때 사용 데이터에 락을 걸어버리는 전략
- 트랜잭션 충돌을 가정하고 시작함
- DB에서 제공하는 공유/배타 락을 사용
- 롤백이 쉬우므로 트랜잭션 충돌이 많이 일어나는 상황에서 사용함
낙관적 락
- 데이터의 변경 버전을 명시하여 데이터 변경 요청에 순서를 부여함, 최초 요청만 인정
- DB 기능을 사용하지 않고 어플리케이션 레벨에서 구현함
- 트랜잭션 및 Lock 사용 X
- 따라서 비관적 락보다 성능이 좋음
- 트랜잭션 충돌이 적은 상황에서 사용함
참고링크
- https://velog.io/@guswns3371/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC%EC%88%98%EC%A4%80
- https://sabarada.tistory.com/121