반응형
트랜잭션과 동시성 제어
트랜잭션이란?
- 갱신은 단일 쿼리가 아닌 복수 쿼리를 연속적으로 수행하는 경우가 대부분
- 또한 갱신 전에 조회를 포함해서 사용하는일이 많음
- 이러한 쿼리들을 한 덩어리로 포함하여 다뤄야 함 → 이런 복수 쿼리를 한 단위로 묶은 것
원자성
- 데이터의 변경을 수반하는 일련의 데이터 조작이 전부 성공할지, 전부 실패할지를 보증하는 구조
- 예를 들어 A, B, C 작업이 순차적으로 있을 경우 A → B → C 가 하일련의 데이터 조작으로 묶임
- 그리고 A, B, C 중 하나라도 실패할 경우 전부 롤백
- A, B, C 를 하나의 원자 단위로 보는 관점
일관성
- 기존의 데이터 베이스가 데이터 조작 전후에 그 상태를 유지하는 것을 보증
- 이를 위해 데이터베이스에서는 오브젝트에 대해 각종 정합성 제약을 추가할 수 있다.
- EX ) 유니크, NOT NULL 등등, 범위 등등
- EX) 성별은 남/여 두가지로 만 설정한다, 잔액은 0보다 커야 한다.
고립성
- 각각의 처리가 모순없이 실행되는 것을 보증하는것
- '모순없이 실행된다' 라는 의미는 복수의 트랜잭션이 순서대로 실행되는 경우와 같은 결과를 얻을 수 있는 상태.
- 즉 병렬로 실행이 되더라도 직렬로 실행된 상태와 동일하다면 '모순 없음'을 보장한다.
- 다만 이런 직렬화 수준의 고립성은 동시에 동작하는 트랜잭션 1개와 동일한 수준 이며, 이는 성능에서 실용적이지가 않습니다.
- 그렇기 때문에 이러한 수준을 완화해 제공하고 있다
- 커밋되지 않은 읽기
- 커밋된 읽기
- 반복 읽기
- 직렬화 가능
- 4번 직렬화 가능 수준이 가장 엄격한 단계이며 1번 커밋되지 않은 읽기가 가장 완화된 단계이다.
- 그러나 격리화 수준이 완화되면서 4단계에서 발생하지 않았던 현상이 생김
- 더티 읽기
- 아직 커밋도지 않은 데이터를 다른 트랜잭션에서 읽는 현상
- 애매한 읽기
- 어떤 트랜잭션이 이전에 읽어 들인 데이터를 다시 읽어 들일 때 2회 이후의 결과가 1회 때와 다른 현상
- TX1 이 특정 조건을 만족하는 행을 검색 → A 출력
- TX2 가 특정 조건에 만족하는 행을 UPDATE → A는 변경
- A는 TX2의 UPDATE 로 인해 특정 조건을 불충족 하는 데이터로 변경
- TX2가 COMMIT
- TX1이 특정 조건을 만족하는 행을 UPDATE를 실행
- A는 특정 조건을 만족하지 않음으로 UPDATE가 실행되지 않음
- TX1이 의도했떤 내용과는 다르게 데이터가 동작
- TX1에서 최초 검색시 A가 특정 조건을 만족했지만 두번째 UPDATE 시에는 A는 특정 조건을 미충족
- 최초 검색시와 UPDATE 시에 대상이 달라지는 현상이 발생
- 어떤 트랜잭션이 이전에 읽어 들인 데이터를 다시 읽어 들일 때 2회 이후의 결과가 1회 때와 다른 현상
- 팬텀 읽기
- 어떤 트랜잭션을 읽을 때 선택할 수 있는 데이터가 나타나거나 사라지는 현상이다.
- TX1이 INSERT 쿼리를 통해 A를 삽입
- TX2가 INSERT 쿼리를 통해 B를 삽입
- TX2 COMMIT
- TX1이 INSERT 쿼리를 통해 C를 삽입
- TX1 COMMIT
- 위와 같은 경우에 TX1 입장에서는 총 삽입한 데이터가 2건, TX2 입장에서는 1건
- 하지만 실제 조회시 총 3건이 나옴
- 어떤 트랜잭션을 읽을 때 선택할 수 있는 데이터가 나타나거나 사라지는 현상이다.
- 더티 읽기
지속성
- 데이터 조작을 완료하고 COMMIT 이후 그 조작은 영구적이 되어 그 결과를 잃지 않는 것을 나타냄
- 쉽게 DB서버를 내렸다 올려도 이전에 조작이 완료된 데이터는 보존이 되어 있어야 한다.
- OS 이상종료, 시스템 장애 등등 이러한 상황에서도 지속성은 보장이 되어야 한다.
트랜잭션 격리 수준에 따른 외관상 차이
MVCC 에 따른 MySQL 의 특성
- MySQL(InnoDB 형 테이블) 은 현재 DBMS 의 주류가 된 'MVCC'라는 기술을 사용하고 있다.
- MVCC는 다음과 같은 특성을 지닌다.
- 읽기를 수행할 경우 갱신 중이라도 블록되지 않는다.
- 읽기 내용은 격리 수준에 따라 내용이 바뀌는 경우가 있다.
- 갱신 시 베타적 잠금을 얻는다.
- 갱신과 갱신은 나중에 온 트랜잭션이 잠금을 획득하려고 할 때 블록된다.
- 갱신 전 데이터를 UNDO 로그로 '롤벡 세그먼트' 라는 영역에 유지한다.
- UNDO 로그는 롤백시 갱신 전으로 되돌리기 위해
- UNDO 로그는 복수의 트랜잭션으로부터 격리 수준에 따라 대응하는 갱신 데이터를 참조 하는데 이용(다른 트랜잭션이 읽기를 수행한다면 해당 데이터를 제공)
트랜잭션 격리 수준별 외관
- MVCC에 따른 MySQL 특성상 격리 수준의 기본값은 반복 읽기
반복 읽기
- 반복 읽기는 최초 쿼리를 실행한 시점에 커밋된 데이터를 읽음
- 복수 회 실행을 해도 최초 실행한 것과 동일한 결과를 반환
- 복수 회 실행 중 다른 트랜잭션이 데이터를 변경해도 최초 실행한 것과 동일한 결과를 반환
커밋된 읽기
- 쿼리를 실행한 시점에서 커밋된 데이터를 읽음
- 복수 회 실행 중 다른 트랜잭션에서 커밋할때, 커밋된 데이터를 읽어옴
잠금 타임아웃과 교착 상태가 발생하는 이유
잠금 타임아웃이란?
- 갱신과 참조는 서로를 블록하지 않음
- 갱신과 갱신은 나중에 온 갱신이 잠금 대기 상태가 됨
- 잠금 해제를 기다리고 있는 쪽에서는 잠금을 기다리거나, 기다리지 않거나, 기다린다면 어느정도 기다릴지를 설정할 수 있음
- 잠금 대기로 타임아웃이 발생할 경우 DMBS로 부터 롤백되는 단위가 다를때가 있음
- 해당 트랜잭션 전체 롤백
- 타임아웃이 발생한 쿼리만 롤백 (MySQL 기본 설정)
교착 상태란?
- TX1이 A 잠금을 얻음
- TX2가 B 잠금을 얻음
- 서로 잠금을 건 자원에 잠금이 필요한 처리 (UPDATE/INSERT/DELETE) 를 실행하면 아무리 기다려도 상황이 바뀌지 않는 상태가 됨
- 이런 비슷한 상황들을 교착 상태라고 함
교착 상태의 빈도는 낮추는 대책
- 잠금 타임아웃은 일정 시간 기다리면 상황이 개선될 가능성이 있음. (잠금을 건 쪽에서 잠금을 풀 경우)
- 교착 상태는 상황이 개선될 가능성이 없음
- 일반적으로 DBMS에서는 교착 상태를 독자적으로 감지해 상태를 보고함, 그후 한쪽 트랜잭션을 롤백함
교착 상태의 발생 빈도를 낮추기 위한 고려 사항
- 트랜잭션을 자주 커밋한다. 이에 따라 트랜잭션은 더 작은 단위가 되어 교착 상태의 가능성을 낮춘다.
- 정해진 순서로 테이블에 엑세스 하게 한다. 예를 들어서 테이블에 접근할때는 무조건 테이블 간 선행 관계를 정해 접근하도록 하는것
- 필요없는 경우 읽기 잠금 획득의 사용을 피한다.
- 쿼리에 의한 잠금 범위를 더 좁히거나 잠금 정도를 더 작은 것으로 한다. 예를 들어 잠금 단위를 행으로 변경하거나 격리 수준을 느슨하게 설정한다.(반복일기 → 커밋된 읽기)
- 복수 행을 복수 연결이 사용할 경우 테이블 단위 잠금을 획득해 갱신을 직렬화 하는 방법도 있음 → 동시성 저하
- MySQL(InnoDB)의 대책 : 적절한 인덱스를 추가해 해당 인덱스가 사용하게 한다. 인덱스가 없다면 스캔한 모든 행에 잠금이 걸리게 된다.
해서는 안 되는 트랜잭션 처리
1. 오토커밋
- 간단한 쿼리의 실행과 테스트를 하는 경우에는 편리하지만 일정 수 이상의 갱신을 수행하거나 틀내잭션 기능등은 적절한 단위와 격리수준을 이용해 오토커밋을 피하도록 하자
2. 긴 트랜잭션
- 긴 트랜잭션은 데이터베이스 트랜잭션의 동시성이나 자원의 유효성을 저하시킴
2.1 대량 처리를 한개의 트랜잭션이 실행한다.
- 한개의 트랜잭션으로 대량의 갱신 처리를 실행하면 대량 갱신 처리를 롤백하기 위한 대량의 UNDO 로그를 트랜잭션 종료까지 유지해야 한다.
- 적절한 크기를 생각해 트랜잭션을 설정해야 한다.
2.2 아무것도 하지 않는 트랜잭션을 유의한다.
- SELECT를 하고 아무것도 하지 않고 있다면 이 테이블의 반복 읽기 유지를 위해 UNDO 로그가 계속 유지된 상태고 됨
2.3 트랜잭션 중에 대화 처리를 넣는다.
- 효율 적으로 다루기 위해서는 언제 끝날지를 알 수 없는 불명확한 처리를 포함해서는 안됨
- 불명확한 처리 중 가장 대표적인 것이 사용자와의 대화 처리
- 일반적인 처리에 비해 타임아웃 설정을 하지 않는 이상 끝없이 사용자의 처리를 기다리게 됨
- 시스템 전체 효율을 떨어트림
2.4. 처리 능력 이상의 트랜잭션 수
- 트랜잭션이 많다면 잠금 타임아웃이나 교착 상태의 확률이 증가함
- 테스트를 통한 설정이 상한선이 필요함
반응형
'IT > 데이터베이스' 카테고리의 다른 글
JPA 공부 - 0 (0) | 2021.01.17 |
---|---|
백업과 복구 (0) | 2021.01.09 |
데이터베이스와 아키텍쳐 구성 (0) | 2021.01.07 |
H2 Database not found (2) | 2019.12.03 |
ORACLE 전체 테이블 검색 (0) | 2019.04.15 |