트랜잭션의 ACID 특징과 무결성에 대해서 알아봅니다.
트랜잭션
: 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위무결성
: 데이터의 정확성, 일관성, 유효성을 유지하는 것ACID
: 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어
- 의미: 데이터베이스의 상태를 변화시키기 위해 수행하는 논리적인 단일 작업 단위
- 트랜잭션은 논리적인 이유로 여러 쿼리를 단일 작업으로 묶어서 나눠질 수 없게 만든 것이다.
- 트랜잭션의 모든 쿼리가 성공해야 DB에 반영된다.
- 쿼리문 중 일부만 성공해서 DB에 반영되는 일은 발생하지 않는다.
- 트랜잭션의 특징에는 원자성, 일관성, 격리성, 지속성이 있으며, 이를 묶어서 ACID 특징이라고 칭한다.
“All or Nothing”
-
의미: 트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았거나를 보장하는 것
- 즉, 트랜잭션이 성공하여 데이터베이스에 모두 반영되거나, 그게 아니라면 아무것도 반영되지 않아야 한다.
- 트랜잭션 실행 도중 작업에 문제가 생겨 실패하면, 지금까지의 작업을 모두 취소하여 아무 일도 없었던 것처럼 롤백해야 한다.
-
예시: 계좌 이체를 처리하는 과정에서 송금액을 먼저 출금하고 그 다음에 수금자의 계좌에 입금하는 트랜잭션이 실행될 때, 중간에 시스템 오류로 인해 출금만 이루어졌다면 이체는 취소되어야 하며 출금 이전 상태로 되돌려야 한다.
-
커밋과 롤백
- 커밋(COMMIT)
- 지금까지의 작업 내용을 정상적으로 처리하겠다고 확정하는 명령어로, 처리과정을 DB에 영구 저장하는 것
- 커밋을 수행하면 하나의 트랜잭션 과정이 종료된다. (= 하나의 트랜잭션이 성공적으로 수행되었다)
- 롤백(ROLLBACK)
- 지금까지의 작업 내용을 모두 취소하고 트랜잭션 이전 상태로 되돌리는 것
- 롤백 수행 후 트랜잭션이 종료된다.
- 역할 구분
- DBMS - 커밋과 롤백 실행 시 데이터베이스에 영구적으로 저장하는 것과 이전 상태로 되돌린다.
- 개발자 - 언제 커밋하거나 롤백할지 결정한다.
- 이러한 커밋과 롤백 덕분에 데이터의 무결성이 보장된다. 또한, 데이터 변경 전에 변경 사항을 쉽게 확인할 수 있고 해당 작업을 그룹화할 수 있다.
- 커밋(COMMIT)
-
주의 사항
- 만약 외부 API 호출이 있다면 롤백이 일어났을 때 어떻게 해야 할 것인지에 대한 해결 방법이 있어야 하며 트랜잭션 전파를 신경써서 관리해야 한다.
트랜잭션 전파: 여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것
-
의미: ‘허용된 방식’으로만 데이터를 변경해야 하는 것
- 허용된 방식: 데이터베이스에 기록된 모든 데이터는 여러 가지 조건, 규칙에 따라 유효함을 가져야 한다.
- 트랜잭션은 데이터베이스 상태를 consistent 상태에서 또 따른 consistent 상태로 변경해야 한다.
- 데이터베이스에 정의된 규칙을 트랜잭션이 위반했다면 롤백해야 한다.
-
예시: 잔고에 0원이 있는 상태에서 500만 원을 송금하는 것은 불가능하다. 이는 허용된 방식이 아니기 때문이다.
-
역할 구분
- DBMS - 트랜잭션이 데이터베이스에 정의된 규칙을 위반했는지 커밋 전에 확인하고 알려준다.
- 개발자 - 그 외 애플리케이션 관점에서 트랜잭션이 일관성 있게 동작하는지 챙겨야 한다.
-
의미: 트랜잭션 수행 시 서로 끼어들지 못하는 것
- 복수의 정렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 하며, 데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있도록 해야 한다.
-
예시: 여러 사용자가 동시에 같은 상품의 가격을 증가시키려고 할 때, 한 사용자의 변경사항이 다른 사용자의 작업을 방해아면 데이터의 일관성이 깨질 수 있다.
-
격리 수준에 따라 발생하는 현상
- 팬텀 리드(Phantom read)
- 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우를 말한다.
- 중간에 없던 데이터가 생기는 것
- 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우를 말한다.
- 반복 가능하지 않은 조회(None-repeatable read = Fuzzy read)
- 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우를 말한다.
- 중간에 데이터 값이 변경된 것
- 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우를 말한다.
- 더티 리드(Dirty read)
- 한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 행의 데이터를 읽는 경우를 말한다.
→ 위의 이상 현상들을 모두 발생하지 않게 만들면 제약사항이 많아져 동시 처리 가능한 트랜잭션의 수가 줄어들고, 그로 인해 데이터베이스의 전체 처리량(throughput)이 하락하게 된다.
그래서 이 문제를 해결하기 위해 일부 이상 현상을 허용하는 몇 가지 격리 수준을 만들어서 사용자가 필요에 따라 전략적으로 선택할 수 있도록 했다. - 팬텀 리드(Phantom read)
-
격리 수준(Isolation level)
- 의미: 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 수준
- 격리 수준이 엄격해질 수록 허용하지 않는 현상들이 늘어난다.
- 격리 수준이 높아지면 → 격리성이 높아지는 반면에 동시성이 떨어져 DB 서버의 퍼포먼스가 줄어든다.
- 격리 수준이 낮아지면 → 동시성이 높아져 DB 서버의 퍼포먼스는 좋아지지만 격리성이 떨어져 다른 트랜잭션으로부터 영향을 받을 가능성이 커진다.
-
READ_UNCOMMITED | 세 가지 현상 모두 허용
- 가장 낮은 격리 수준으로, 세 가지 현상 모두를 허용한다.
- 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관 없이 다른 트랜잭션에서 값을 읽을 수 있다.
- 이상 현상에 가장 취약한 반면 동시성이 높아 전체 처리량이 가장 높다.
-
READ_COMMITTED | 반복 가능하지 않은 조회, 팬텀 리드 허용
- 커밋 완료된 데이터에 대해서만 조회를 허용한다.
- 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없다.
- 가장 많이 사용되는 격리 수준이다.
-
REPEATABLE_READ | 팬텀 리드만 허용
- 자신의 트랜잭션이 생성되기 이전의 트랜잭션에서 COMMIT이 된 데이터에 대해서만 조회를 허용한다.
- 새로운 행을 추가하는 것은 막지 않는다.
- MySQL과 MariaDB가 기본으로 사용하는 격리 수준이다.
- MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 된다.
-
SERIALIZABLE | 세 가지 현상 모두 허용하지 않음
- 아예 이상 현상 자체가 발생하지 않는 수준을 의미하며, 트랜잭션을 순차적으로 진행시킨다.
- 가장 단순한 격리 수준이지만 가장 엄격한 격리 수준이다.
- 데이터를 접근할 때, 항상 Lock을 걸고 데이터를 조회한다.
- 성능 문제로 데이터베이스에서 거의 사용되지 않는다.
-
세 가지 이상 현상을 정의하고 어떤 현상을 허용하는지에 따라 각각의 격리 수준이 구분되기 때문에개발자는 격리 수준을 통해 전체 처리량과 데이터 일관성 사이에서의 협의점을 찾아 전략적으로 설계할 수 있다.
전체 처리량(throughput): 단위시간 동안 sender와 receiver가 교환된 데이터의 양
-
의미: 성공적으로 수행된(커밋된) 트랜잭션은 데이터베이스에 영구적으로 저장되는 것
- 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 한다.
- ‘영구적으로 저장한다’라는 말은 일반적으로 HDD, SSD와 같은 비휘발성 메모리에 저장함을 의미한다.
-
예시: 사용자가 새로운 게시물을 작성하고 게시 버튼을 클릭하면 이 작업은 성공적으로 데이터베이스에 저장되고, 시스템 오류가 발생해도 게시물이 사라지지 않아야 한다.
-
DBMS는 이를 위해 체크섬, 저널링, 롤백 등의 기능을 제공한다.(기본적으로 DBMS가 보장하는 부분이다)
체크섬: 중복 검사의 한 형태로, 오류 정정을 통해 송신된 자료의 무결성을 보호하는 단순한 방법
저널링: 파일 시스템 또는 데이터베이스 시스템에 변경사항을 커밋하기 전에 로깅하는 것, 즉 트랜잭션 등 변경사항에 대한 로그를남기는 것
무결성이란 데이터의 정확성, 일관성, 유효성을 유지하는 것을 말한다.
무결성이 유지되어야 데이터베이스에 저장된 데이터 값과 그 값에 해당하는 현실 세계의 실제 값이 일치하는지에 대한 신뢰가 생긴다.
- 개체 무결성
- 기본키를 구성하는 어떤 속성도 NULL값 이나 중복값을 가질 수 없다.
- 기본키는 유일성과 최소성을 만족해야 한다.
- 기본키를 구성하는 어떤 속성도 NULL값 이나 중복값을 가질 수 없다.
- 참조 무결성
- 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 한다.
- 릴레이션은 참조할 수 없는 외래키 값을 가질 수 없다.
- 외래키 값은 NULL 이거나 참조 릴레이션의 기본키 값과 동일해야 한다.
- NULL은 허용되는 이유: 빈값이기 때문에 참조 릴레이션을 참조하지 않는다.
- 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 한다.
- 고유 무결성
- 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가져야 한다는 제약 조건이다.
- NULL 무결성
- 특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 그 속성 값은 NULL이 될 수 없다는 제약 조건이다.
NULL: 아무것도 입력되지 않은 빈 상태
- 본문 출처
- 이미지 출처