데이터베이스 트랜잭션(Transaction)

eomprgrm·2023년 4월 14일
0

1. 트랜잭션(Transaction)이란?


데이터베이스에서 트랜잭션(Transaction)은 하나의 논리적인 작업 단위를 나타낸다.
이 작업은 데이터베이스에서 데이터를 읽거나 쓰는 것과 같이 데이터베이스 상태를 변경하는 모든 연산들의 집합으로 구성된다.

INSERT,
SELECT,
UPDATE,
DELETE

2. 트랜잭션의 특성


트랜잭션은 논리적인 완전성을 유지하기 위해 반드시 지켜야할 네 가지 특성(ACID)이 있다.

ACID

  • 원자성 (Atomicity)
    • 트랜잭션 내의 모든 연산이 일괄적으로 수행되거나, 전혀 수행되지 않아야 한다는 것을 보장한다. 즉, 하나의 연산이라도 실패할 경우 트랜잭션 전체가 실패하여야 한다.
  • 일관성 (Consistency)
    • 트랜잭션이 실행된 이후에도 데이터베이스가 일관된 상태를 유지해야 한다는 것을 보장한다. 트랜잭션의 결과는 언제나 일관성 있는 상태를 유지해야 한다.
  • 격리성 (Isolation)
    • 여러 개의 트랜잭션이 동시에 실행될 경우, 각 트랜잭션이 서로에게 영향을 미치지 않도록 격리되어야 한다는 것을 보장한다. 따라서 트랜잭션의 작업 결과를 볼 수 없고, 다른 트랜잭션의 작업 결과를 볼 수 없도록 보장되어야 한다.
  • 지속성 (Durability)
    • 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 저장되어야 한다는 것을 보장한다. 시스템에 장애가 발생하더라도, 트랜잭션이 완료된 이후의 데이터 상태는 유지되어야 한다.

3. Commit, Rollback


Commit

커밋(Commit)은 트랜잭션의 작업 결과를 데이터베이스에 영구적으로 반영하는 것을 의미한다. 트랜잭션이 성공적으로 실행되었을 경우, 커밋을 통해 데이터베이스에 변경된 내용이 반영되어 다른 사용자들도 변경된 내용을 조회할 수 있다.

트랜잭션의 작업은 일련의 단계로 이루어지며, 이 중 커밋 이전에는 작업 내용이 일시적으로 데이터베이스에 반영되지 않는다. 이를 '임시 저장소(temporay storage)' 또는 '버퍼(buffer)'라고 부른다. 즉, 커밋 이전에는 데이터베이스에 대한 작업 내용은 시스템의 메모리에 저장되어 있으며 이후 커밋을 실행함으로써 데이터베이스에 실제로 반영된다.

Rollback

Rollback은 트랜잭션 실행 중 문제가 발생했을 때 이전 상태로 복구하기 위한 기능이다. 롤백을 실행하면 트랜잭션 실행 중에 변경한 데이터를 이전 상태로 되돌린다.

트랜잭션을 롤백하는 이유는 트랜잭션 실행 중 문제가 발생했을 때, 변경된 데이터가 영구적으로 저장되기 전에 이전 상태로 복구할 수 있도록 하기 위해서이다.

Rollback 예시
- 은행 서비스에서 계좌 이체 도중 보내는 이의 통장에서 돈은 빠져나갔지만, 트랜잭션 내에서 다음 상황에 문제가 생겨 실패하여 받는 이에게 정상적으로 이체가 되지 못 했을 때(트랜잭션 실패, 롤백 필요) 보내는 이의 통장을 이체하기 이전 상태로 돌려놓는다.

4. 트랜잭션 격리수준


트랜잭션 격리수준(Isolation Level)은 동시에 실행되는 여러 개의 트랜잭션에서 데이터를 어떻게 공유하고 동기화할 것인지를 결정하는 것을 의미한다.

트랜잭션 격리수준에는 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE 네 가지가 있다.

  • READ UNCOMMITTED (커밋되지 않은 읽기)
    • 다른 트랜잭션이 커밋되지 않은 데이터를 읽을 수 있다.
    • Dirty Read, Non-repeatable Read, Phantom Read 문제가 발생한다.
  • READ COMMITTED (커밋된 읽기)
    • 다른 트랜잭션이 커밋된 데이터만 읽을 수 있다.
    • Dirty Read는 발생하지 않지만 Non-repeatable Read, Phantom Read 문제는 발생할 수 있다.
  • REPEATABLE READ (반복 가능한 읽기)
    • 트랜잭션이 시작되면 읽은 데이터의 스냅샷을 만들고, 이 스냅샷을 유지한다.
    • 다른 트랜잭션이 데이터를 수정하더라도 해당 트랜잭션은 이전에 읽었던 데이터를 계속해서 읽게 된다.
    • Dirty Read와 Non-repeatble은 발생하지 않지만 Phantom Read는 발생할 수 있다.
  • SERIALIZABLE (직렬화 가능한)
    • 가장 엄격한 격리 수준이다.
    • 트랜잭션이 실행 중일 때 사용 중인 테이블의 모든 행을 다른 트랜잭션에서 접근할 수 없도록 Lock(잠금)을 건다.
    • 성능이 가장 떨어진다.

5. 트랜잭션 격리 수준에 따른 문제


  • Dirty Read
    • 트랜잭션이 아직 커밋되지 않은 데이터를 읽는 것이다. 이 때 다른 트랜잭션이 해당 데이터를 수정하고 롤백하는 경우 첫 번째 트랜잭션은 잘못된 데이터를 읽게 된다.
    • 예시) A 트랜잭션에서 홍길동의 나이를 20살로 변경 (아직 커밋하지 않은 상태) B 트랜잭션에서 홍길동의 나이를 조회함 (20살이 조회) 이 상태에서 A 트랜잭션이 롤백을 하여 홍길동의 나이가 20살에서 19살로 돌아감. 그러나 B 트랜잭션은 여전히 20살로 인식하여 다음 로직을 수행한다.
  • Non-repeatable Read
    • 트랜잭션이 같은 데이터를 두 번 읽었을 때, 다른 트랜잭션에 의해 해당 데이터가 수정되어 다른 값이 나오는 것이다.
    • 예시) A 트랜잭션에서 홍길동의 나이를 조회한다. 19살이 조회되었다. B 트랜잭션에서 홍길동의 나이를 20살로 변경하고 커밋한다. A 트랜잭션이 아직 끝나지 않은 상태에서 홍길동의 나이를 다시 조회하는 로직을 수행하였는데 20살이 조회된다.
  • Phantom Read
    • 트랜잭션이 같은 쿼리를 두 번 실행하였을 때, 다른 트랜잭션에 의해 새로운 데이터가 추가되거나 결과가 다른 것이다.
    • 예시) 트랜잭션 A에서 나이가 20살인 회원을 검색하였고 3명이 조회되었다. 이 때 B 트랜잭션에서 나이가 20살인 새 회원을 INSERT 하고 커밋하였다. 아직 끝나지 않은 트랜잭션 A에서 나이가 20살인 회원을 검색하는 쿼리를 재실행 하였을 때 이전의 3명이 아닌 4명이 조회되는 것이다.
profile
성실하고 둥글게 살고자 하는 개발자입니다.

0개의 댓글