[Database] 트랜잭션 및 ACID 특성
[Database] 트랜잭션 및 ACID 특성
트랜잭션(transation)
- 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
- 간단하게 말해서 질이의(SQL, SELECT, INSERT, DELETE, UPDATE)를 이용하여 데이터베이스에 접근 하는 것을 의미
- 착각하지 말아야 할 것은, 작업의 단위는 질의어 한 문장이 아니라는 점
- 작업단위는 많은 질의의 명령문들을 사람이 정하는 기준에 따라 정하는 것을 의미
- 질의(query)를 하나의 묶음 처리해서 만약 중간에 실행이 중단되면 처음부터 다시 실행하는 Rollback을 수행하고, 오류없이 실행을 마치면 commit을 하는 실행 단위
- 즉, 한 번 질의가 실행되면 질의가 모두 수행되거나 모두 수행되지 않는 작업수행의 논리적 단위
- ex) 친구에게 인터넷 뱅킹으로 10000원을 송금할 때, 저의 계좌에서 10000원을 줄이고 친구의 계좌에 10000원을 증가시켜야 하는데, 오류가 나면 다시 처음부터 송금을 하는것이 rollback
즉, 송금 과정을 하나의 transation으로 볼 수 있음
- DBMS의 성능은 초당 트랜잭션의 실행 수(TPS : Transaction per second)로 측정
특성
트랜잭션은 아래의 4가지 특성이 존재
4가지 특성의 앞 글자만 따서 ACID특성 함
1. 원자성(Atomicity)
- 트랜잭션의 작업이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 것
- 즉 All or Nothing의 개념으로서, 부분만 실행되지 않는다는 것을 의미함
2. 일관성(Consistency)
- 트랜잭션이 성공적으로 완료되면 일관적인 DB상태를 유지하는 것
- 여기서 말하는 일관성이란 데이터 타입이 갑자기 정수형(integer)에서 문자열(string)이 되지 않는 것
3. 격리성(Isolation)
- 트랜잭션 수행시 다른 트랙젝션은 작업에 기어들지 못하도록 보장
- 즉, 트랜잭션끼리는 서로를 간섭 불가
4.지속성(Durability)
- 성공적으로 수행된 트랜잭션은 영원히 반영이 됨
- commit을 하면 현재 상태에 영원히 보장
격리성 관련 문제점
Dirty Read
한 트랜잭션(T1)이 데이터에 접근하여 값을 'A'에서 'B'로 변경했고 아직 커밋을 하지 않았을 때, 다른 트랜잭션(T2)이 해당 데이터를 Read 하면?
T2가 읽은 데이터는 B가 될 것이다. 하지만 T1은 최종 커밋을 하지 않고 종료된다면, T2가 가진 데이터는 꼬이게 된다.
커밋되지 않은 수정 중인 데이터를 다른 트랜잭션내에 읽을 수 있도록 허용할 때 발생
대부분 DBMS가 기본 트랜잭션 고립화 수준을 레벨1로 설정하고 있어 Dirty Read는 발생하지 않음
= 커밋된 데이터만 읽을 수 있도록 허용
Non-Repeatable Read
한 트랜잭션(T1)이 데이터를 Read하고 있다.
이 때 다른 트랜잭션(T2)가 데이터에 접근하여 값을 변경 또는, 데이터를 삭제하고 커밋을 때려버리면?
그 후 T1이 다시 해당 데이터를 Read하고자 하면 변경된 데이터 혹은 사라진 데이터를 찾게 된다.
한 트랜잭션내에서 같은 쿼리를 두 번 수행할 때 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리의 결과가 상이하게 나타나는 비일관성이 발생하는 것을 말함.
Phantom Read
하지만 Non-Repeatable Read는 데이터를 변경시키지 못할 뿐 새로운 데이터를 추가는.?
트랜잭션(T1) 중에 특정 조건으로 데이터를 검색하여 결과를 얻었다.
이 때 다른 트랜잭션(T2)가 접근해 해당 조건의 데이터 일부를 삭제 또는 추가 했을 때,
아직 끝나지 않은 T1이 다시 한번 해당 조건으로 데이터를 조회하면
아직 끝나지 않은 T1이 다시 한번 해당 조건으로 데이터를 조회하면
T2에서 추가/삭제 된 데이터가 함께 조회/누락 된다.
그리고 T2가 롤백을 하면? 데이터가 꼬인다.
한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때, 첫번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상
이는 트랜잭션 도중 새로운 레코드가 삽입되는것을 허용하기 때문에 나타나는 현상
트랜잭션 격리수준
위와 같은 문제들 때문에, ANSI표준에서 트랜잭션의 격리성과 동시 처리 성능 사이의 Trade-off를 두고 4단계 격리수준으로 나누었다.
내려갈수록 격리 수준이 높아져서 언급된 이슈는 적게 발생하지만 동시 처리 성능은 떨어진다.
참고로, 트랜잭션이 발생하면 락(Lock)이 걸리는데,
SELECT시에는 공유 락,
CREATE/INSERT/DELETE시에는 배타적 락이 걸린다.
Read Uncommitted
즉, 커밋하지 않은 데이터를 읽을 수 있다.
- 이 수준은 당연히 위에서 언급한 모든 문제에 대해 발생가능성이 존재한다.
대신, 동시 처리 성능은 가장 높다. - 발생 문제점 : Dirty Read, Non-Repeatable Read, Phantom Read
Read Committed
- Transaction 2가 Update를 하게 됩니다.
- 아직 커밋하지 않아 Transaction 1은 Select를 하지 못하고 대기하게 됩니다.
- Transaction 2가 Commit명령어를 날리게 됩니다.
- 이제 Transaction 2는 조회가 가능합니다.
- 조회 시 데이터에 대한 Shared lock이 됩니다.
- Read Uncommitted와 다르게 Commit이 이루어진 데이터가 조회됩니다.
- 하지만 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 Transaction은 접근할 수 없어 대기하게 됩니다.
- Dirty Read가 발생할 여지는 없으나, Read Uncommitted 수준보다 동시 처리 성능은 떨어진다.
- 대신 Non-Repeatable Read 및 Phantom Read는 발생 가능하다.
데이터베이스들은 보통 Read Committed를 디폴트 수준으로 지정한다. - 발생 문제점 : Non-Repeatable Read, Phantom Read
Repeatable Read
- Transaction 1이 Select시점에 아무개가 조회됩니다.
- Transaction 2가 Update 후 Commit을 시행했지만 Update가 안됩니다.그러나 Insert는 됩니다.
- Transaction 1이 다시 조회 해봐도 Transaction2가 Commit되지 않았기 때문에 아무개로 조회됩니다.
하지만 Insert한 동네 개발자는 조회됩니다. - Transaction1이 종료되면서 다시 Commit이 이루어지기 때문에 개발자로 조회가 됩니다.
트랜잭션 내에서 한번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회 된다.
- 이는 개별 데이터 이슈인 Dirty Read나 Non-Repeatable Read는 발생하지 않지만, 결과 집합 자체가 달라지는 Phantom Read는 발생가능하다.
- 발생 문제점 : Phantom Read
Serializable
가장 엄격한 격리 수준
- 위 3가지 문제점을 모두 커버 가능하다
하지만 동시 처리 성능은 급격하게 떨어질 수 있다. - 말 그대로 직렬화를 이야기합니다. 그래서 모든 동작이 직렬화 되어 작동합니다. Repeatable Read와 다르게 Insert를 하여도 작동하지 않게 됩니다.
출처
댓글
댓글 쓰기