CS 지식/OS
데이터베이스 :: 트랜잭션
경토리
2024. 12. 1. 16:46
728x90
트랜잭션
- 트랜잭션은 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
- 데이터베이스의 상태를 변화시킨다는 말은 질의어(SQL)를 이용하여 데이터베이스에 접근하는 것
- 한꺼번에 수행되어야 할 연산을 모아놓은 것 ⇒ 연산들을 모두 처리하지 못 한 경우에는 원 상태로 복구한다. 즉 작업의 일부만 적용되는 현상이 발생하지 않는다.
- SELECT
- INSERT
- DELETE
- UPDATE
- ex) 게시판
- 게시판 사용자는 게시글을 작성하고 올리기 버튼을 누른다.
- 그 후에 다시 게시판에 돌아왔을 때, 게시판은 자신의 글이 포함된 업데이트된 게시판을 보게된다.
- 이러한 상황을 데이터베이스 작업으로 옮기면 사용자가 올리기 버튼을 눌렀을 시 INSERT문을 사용하여 사용자가 입력한 게시글의 데이터를 옮긴다.
- 그 후에 게시판을 구성할 데이터를 다시 SELECT 하여 최신 정보로 유지한다.
- 여기서 작업의 단위는 INSERT, SELECT 문 둘 다를 합친 것이다. ⇒ 이러한 작업단위를 하나의 트랜잭션 이라고 한다.
트랜잭션의 특징
- Atomicity 원자성
- 트랜잭션이 데이터베이스에 모두 반영되거나 아니면 전혀 반영되지 않아야 한다는 것
- 트랜잭션은 사람이 설계한 논리적인 작업 단위로서 일처리는 작업 단위 별로 이루어져야 사람이 다루는데 무리가 없다.
- 만약 트랜잭션 단위로 데이터가 처리되지 않는다면 설계한 사람은 데이터 처리 시스템을 이해하기 힘들 뿐만 아니라 오작동 했을 시 원인을 찾기가 매우 힘들어 질 것이다.
- Consistenty 일관성
- 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것이다.
- 트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트 된 데이터베이스로 트랜잭션이 진행되는 것이 아니라 처음에 트랜잭션을 진행하기 위해 참조한 데이터베이스로 진행된다.
- 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것이다.
- Isolation 독립성, 격리성
- 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다는 것을 가리킨다.
- 하나의 특정 트랜잭션이 완료될 때까지 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.
- 독립성, 고립성을 구현하는 개념 ⇒ 격리수준
- 동시에 여러 트랜잭션이 처리될 때 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것
- Durability 지속성
- 트랜잭션이 성공적으로 완료됐을 경우 결과는 영구적으로 반영되어야 한다는 점이다.
트랜잭션의 Commit, Rollback 연산
- Commit
- 트랜잭션이 성공적으로 수행되었음을 선언하는 연산
- 하나의 트랜잭션이 성공적으로 끝났고 데이터베이스가 일관성있는 상태에 있을 때 하나의 트랜잭션이 끝났다라는 것을 알려주기 위해 사용하는 연산
- Rollback
- 트랜잭션 수행이 실패했음을 선언하고 작업을 취소하는 연산
- 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진 경우 트랜잭션을 처음부터 다시 시작하거나 트랜잭션의 부분적으로만 연산된 결과를 다시 취소시킨다.
트랜잭션의 격리수준
- ACID 중 Isolation(독립성, 고립성)을 구현하는 개념
- 동시에 여러 트랜잭션이 처리될 때 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것
- 즉, 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것
- 격리수준은 아래의 4가지로 구분
- READ UNCOMMITTED
- READ COMMITED
- REPEATABLE READ
- SERIALIZABLE
- 아래로 내려갈수록 트랜잭션 간 고립 정도가 높아지며 성능이 떨어지는 것이 일반적
- 일반적인 온라인 서비스에서는 READ COMMITED나 REPEATABLE READ 중 하나를 사용
- (oracle의 디폴트 = READ COMMITED, MySQL의 디폴트 = REPEATABLE READ)
격리수준의 필요성
- DB는 ACID 특징과 같이 트랜잭션이 독립적인 수행을 하도록 한다.
- 따라서 Locking을 통해 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하도록 막는 것이 필요하다.
- 하지만 무조건 Locking으로 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하는 방식으로 구현하게 되면, DB의 성능은 떨어지게 된다.
- 그렇다고 성능을 높이기 위해 Locking의 범위를 줄인다면 잘못된 값이 처리될 문제가 발생하게 되므로, 최대한 효율적인 Locking 방법이 필요하다.
트랜잭션 격리수준의 종류
READ UNCOMMITTED (레벨 0) - 커밋되지 않는 읽기
- 각 트랜잭션에서의 변경 내용을 COMMIT 이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 값을 읽을 수 있다.
- 정합성에 문제가 많은 격리 수준이기 때문에 사용하지 않는 것을 권장.
- DIRTY READ 현상 발생 ⇒ 더러운 읽기 발생
- DIRTY READ: 트랜잭션 작업이 완료되지 않았음에도 다른 트랜잭션에서 볼 수 있게 됨
READ COMMITED (레벨 1) - 커밋된 읽기
- RDB에서 대부분 기본적으로 사용되고 있는 격리 수준
- 실제 테이블 값을 가져오는 것이 아니라, Undo 영역에 백업된 레코드에서 값을 가져옴
- DIRTY READ와 같은 현상 발생 X
- Non-repeatable Read 현상 발생
- Non-repeatable Read: 한 트랜잭션에서 같은 쿼리를 두 번 수행할 때, 그 사이에 다른 트랜잭션 값을 수정 or 삭제하면서 두 쿼리의 결과가 상이하게 나타나는 일관성이 깨진 현상
REPEATABLE READ (레벨 2) - 반복가능한 읽기
- Undo 공간에 백업해두고 실제 레코드 값을 변경
- MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여해 트랜잭션 ID보다 작은 번호에서 변경한 것만 읽음
- 백업된 데이터는 불필요하다고 판단하는 시점에 주기적으로 삭제
- Undo에 백업된 레코드가 많아지면 MySQL 서버의 처리 성능이 떨어질 수 있음
- 이러한 변경방식을 MVCC(Multi Version Concurrency Control) 라고 부름
- PHANTOM READ 현상 발생
- PHANTOM READ: 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안 보였다가 하는 현상
- REPEATABLE READ 에 의하면 원래 출력되지 않아야 하는데 Update 영향을 받은 후부터 출력
- 방지 방법: 쓰기(write) 잠금을 걸어야 함
SERIALIZABLE (레벨 3) - 직렬화 가능
- 가장 단순한 격리 수준이면서 가장 엄격한 격리 수준
- 완벽한 읽기 일관성 모드 제공
- 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력 불가능
- 성능 측면에서는, 동시 처리 성능 가장 낮음
- PHANTOM READ 발생 X
- DB에서 거의 사용 X
정리 :: 낮은 격리수준을 활용했을 때 발생하는 현상들
이 현상들은 트랜잭션의 Isolation(고립성)과 데이터 무결성의 지표로 사용된다.
- Dirty Read트랜잭션이 종료되면 더이상 존재하지 않거나, 롤백되었거나, 저장 위치가 바뀌었을 수도 있는 데이터를 읽어들이는 현상
- 생성, 갱신 또는 삭제 중에 커밋되지 않은 데이터 조회를 허용함으로써,
- Non-repeatable Readex) A와 B가 마지막 남은 영화표를 예매하는데, A가 고민하는 중에 B가 표를 구매하여 A는 상반된 정보를 받게 되는 경우
- 한 트랜잭션 내에서 같은 행이 두 번 이상 조회됐는데 그 값이 다른 경우
- Phantom Read첫 번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상
728x90