[데이터베이스] - 트랜잭션 ( + ACID)

링딩·2023년 3월 27일
0

Computer Science

목록 보기
13/49

* DBMS(DataBase Management System) :

사용자의 요청을 해석하여 데이터베이스에 저장된 정보를 관리할 수 있게 도와주는 소프트웨어
ex) MySQL, Oracle DB, Maraia DB 등

SQL : RDBMS에 저장된 데이터를 관리하기 위해 설계가 된 프로그래밍 언어


✨트랜잭션

* 정의 : 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위

=> "하나의 논리적 작업 단위를 구성하는 일련의 연산들의 집합"
=> 즉, 이 트랜잭션을 사용하면 DB의 상태를 변화시킨다는 것이다. (질의어로 DB에 접근하는 것)


✨ 트랜잭션의 간단한 동작 흐름

예를 들어
1. A계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.
2. B계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.
3. A 계좌에서 10000원을 인출한 값을 저장한다.
4. B 계좌에서 10000원을 입금한 값을 저장한다.
5. A 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.
6. B 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.

[간단한 용어 정리]

  • Commit :
    트랜잭션의 수행이 완료됨을 트랜잭션 관리자에게 알려 주는 연산

이와 같은 상황을 예시로 들었을 때 트랜잭션에는 2가지 방법을 가지고 있다.
이 2가지의 기준은 Commit이 들어가는 위치에 따라 나뉘는데 일반적으로는 사용자에게 빠른 응답을 위해 4번까지 수행 후 -> commit -> 5,6 의 방법 1을 많이 쓴다고 한다.

  • 방법 2 : 6번까지 종료한 후 Commit

[방법 1의 동작]



+) 좀 더 SQL 언어로 어떤 과정을 거치는지 보면

1) BEGIN the transaction

2) EXECUTE several queries
(아직 DB 내에 갱신이 적용되지 않는다)

3) COMMIT the transaction
(트랜잭션 성공, 갱신이 실제 적용됨)

만일 이 2번째 단계에서 쿼리들 중 하나라도 실패하게 된다면?
=> DBMS는 전체 트랜잭션 or 실패한 쿼리를 ROLLBACK 한다. (DBMS 설정에 다르긴 함)




✨ 트랜잭션의 성질 (ACID)

Atomicity(원자성), Consistency(일관성), Isolation(독립성), Durability(영구성) 으로 구성되어 있다.

Atomicity(원자성)

  • 정의
    트랜잭션은 모든 연산들이 정상적으로 수행 완료되거나, 아니면 전혀 어떠한 연산도 수행되지 않은 상태를 보장해야 한다는 성질
    => All or nothing 특성

만약 이체 과정 중 트랜잭션이 실패하면, 옮기던 돈이 사라지는 일이 발생하면 안되므로 완료되지 않은 트랜잭션의 중간상태를 DB에 반영해서는 ❌



Consistency(일관성)

  • 정의
    트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것이다
  • 무슨말인가?🤔
    A라는 상태의 계좌가 트랜잭션을 진행하는 중에 특정요인으로 DB가 변경되어 A->B 상태가 되어도
    B상태의 DB에서 트랜잭션이 진행되는 것이 아닌 초기의 A상태의 DB로 진행된다는 것을 의미한다.

Isolation(독립성)

  • 정의
    여러 트랜잭션이 동시에 수행되더라도 각각의 트랜잭션은 다른 트랜잭션의 수행에 영향을 받지 않고 독립적으로 수행되어야 한다
  • 무슨말인가?🤔
    이 성질을 보장받지 못하면, 특정 트랜잭션이 잘못되어도 원래 상태로 ROLLBACK을 할 수 ❌

Durability(지속성)

  • 정의
    트랜잭션이 성공적으로 완료되어 COMMIT 되고 나면, 해당 트랜잭션에 의한 든 변경은 향후에 어떤 소프트웨어나 하드웨어 장애가 발생되더라도 보존되어야 한다


✨트랜잭션의 상태 (결과)

  • 활동(Active) : 트랜잭션이 실행중인 상태
  • 부분 완료(Partially Committed) : 트랜잭션의 마지막 연산까지 실행, COMMIT 연산은 실행 X
  • 실패(Failed) : 트랜잭션 실행에 오류가 발생하여 중단된 상태
  • 완료(Committed) : 트랜잭션이 성공적으로 종료되어 COMMIT 연산을 실행한 후의 상태
  • 철회(Aborted) : 트랜잭션이 비정상적으로 종료되어 ROLLBACK 연산을 수행한 상태

+) 부분완료와 완료의 차이?🤔

commit요청이 들어오면 상태는 부분완료 상태가 된다. 이후 commit을 문제없이 수행 할 수 있다면 완료 상태로 전이되고, 만약 오류가 발생하면 실패 상태가 된다.
=> 즉, '부분완료'는 commit 요청이 들어왔을 때를 말하며, '완료 상태'는 commit 을 정상적으로 완료한 상태를 말한다.


+) 주의

일반적으로 데이터베이스 커넥션은 개수가 제한적 이므로 이를 소유하는 시간이 길어진다면 사용할 수 있는 커넥션은 점점 줄어들기에 이를 기다리는 시간이 발생할 수 있다!
그러므로 트랜잭션은 필요한 최소의 코드에만 적용하자 👍




✨ 트랜잭션의 고립 수준(Isolation Level)

* 정의

트랜잭션들끼리 일관성 있는 데이터를 얼마나 허용할 것인지 정해놓은 수준
=> 즉, 트랜잭션 수행 중 다른 트랜잭션이 해당 데이터를 조회하는 것이 가능한 정도를 결정해 놓은 것

>고립 수준이 high면? .... 일관성 보장하나 동시성 떨어짐(성능 하락)


◾ 고립수준의 종류

1. READ uncommitted (LEVEL 0)

  • 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 값을 읽을 수 있다.
  • 정합성에 문제가 많은 격리 수준이므로 사용하지 않는 것이 좋다.

😥문제점:
Dirty Read, Non Repeatable Read, Phantom Read 문제가 모두 발생할 수 있다.


2. READ committed (LEVEL 1)

  • 트랜잭션 수행이 완료되고 COMMIT 된 데이터만 다른 트랜잭션에서 READ 하도록 허용하는 수준이다.
  • 일반적으로 DBMS에서 기본으로 설정하는 레벨

트랜잭션 1이 COMMIT 하기 전에 트랜잭션 2의 SELECT 결과는 '제니'였다.

하지만 트랜잭션이 1이 COMMIT 하고 난 후의 SELECT 결과는 '태연'이었다.

😥문제점:
Non Repeatable Read ,이외에 Phantom Read 문제도 발생


3. REPEATABLE READ (LEVEL 2)

  • 이론상 특정 트랜잭션에서 읽고 있는 데이터는 다른 트랜잭션에서 수정/삭제가 불가능하고, 삽입은 가능하다.
  • 트랜잭션에 진입하기 이전에 커밋된 내용만 참조가 가능
  • 실제로 동작하는 방식자신의 트랜잭션 번호(ID) 보다 낮은 트랜잭션 번호에서 변경된(Commit 된) 것만 읽게 되고, 자신의 트랜잭션 번호보다 높은 트랜잭션에서 변경된 것은 UNDO 영역에 백업된 레코드를 읽게 된다
  • UNDO 영역에 백업된 레코드가 많아지면 성능이 떨어질 수 있다.

=> 제니 (Non Repeatable Read 문제 ❌)

REPEATABLE READ에서는 위와 같이 자신의 트랜잭션 번호(10) 보다 높은 트랜잭션 번호(12)에서 변경된 레코드는 UNDO 영역에 백업된 레코드를 읽게 된다.


그러나 PHANTOM READ 문제 발생

위와 같이 트랜잭션 2 내에서 SELECT COUNT(*)-전체 행의 개수를 구하는 쿼리의 결과가 달라질 수 있다.
=> 트랜잭션 1에서 INSERT 쿼리를 수행한 결과가 트랜잭션 2에게 보이기 때문


4. SERIALIZABLE (LEVEL 3)

  • 가장 단순하고 엄격한 격리 수준이다.
  • 모든 동작이 직렬화하게 작동한다.
  • 특정 트랜잭션에서 읽고 있는 데이터는 다른 트랜잭션에서 수정/삭제/삽입이 불가능하다.
  • 동시성이 떨어져서 성능이 하락하여 잘 쓰이지 않는다. 🤪
  • Dirty Read, Non Repeatable Read, Phantom Read 문제가 발생하지 ❌



출처

헬창 백엔드 개발자의 이것저것 블로그 님의 글을 참조하여 작성하였습니다.
code-lab1님의 글을 참조하여 작성하였습니다.


profile
초짜 백엔드 개린이

0개의 댓글