DB | Transaction(트랜젝션)

bubblegum·2024년 1월 28일
0

DB

목록 보기
6/11
post-thumbnail

트랜젝션이란 DB의 완전무결성을 보장해주기 위해 여러 개의 쿼리(Query)을 하나의 작업 단위로 그룹화하여 처리하는 '과정'을 뜻한다. 트랜젝션과 관련된 SQL은 TCL이 있다.

ACID

원자성(Atomicity)

원자성(Atomicity)이란 "나눠질 수 없는 단일 작업"이라는 의미이다. 원자성은 트랜잭션 내에서 실행되는 명령들을 하나의 묶음으로 처리하여, 내부에서 실행된 명령들이 전부 성공하거나, 아니면 모두 실패해야 한다는 특징이다.

일관성(Consistency)

일관성(Consistency)은 트랜잭션 내부에서 처리되는 데이터의 일관성을 유지해야 한다는 특징이다. 만약 작업이 성공할 경우 아무런 문제가 발생하지 않고, 실패하더라도 작업을 진행하던 도중 실패한 상태로 데이터를 방치하지 않아야 한다. SQL 중 TCL이 일관성 특징과 관련이 있는데, 데이터가 정상적으로 업로드 하였다면 COMMIT 명령어로 데이터를 저장하고, 데이터가 부분적으로 업로드 되지 않는다면 ROLLBACK 명령어를 실행하여 트랜잭션 시작 전 상태로 복구한다.

격리성(Isolation)

격리성(Isolation)은 한 트랜잭션의 수행 중에 다른 트랜잭션 수행으로 인한 간섭을 방지하므로써 데이터가 변경되지 않도록 한다는 특징이다. 이러한 특징은 트랜잭션이 완전히 수행되거나 완전히 수행되지 않은 상태를 외부에서 참조할 수는 있지만, 트랜잭션의 중간 과정이나 중간 결과를 볼 수 없도록 한다. 격리성이라는 특징은 동시성 문제와 격리 수준과 관련있다.

  1. 동시성 문제(Concurrency Issue): 여러 클라이언트가 동시에 같은 데이터를 접근하려고 할 때 발생한다. 이러한 문제는 자원을 사용하는 하나의 클라이언트만 해당 자원을 점유할 수 있도록 하여, 다른 사용자가 접근할 수 없도록 만들어 자원을 공유하는 원인을 제거하므로써 해결할 수 있다. 이것을 자원 잠금(Resource Locking)라고 하며 흔히 (Lock)이라고 부른다.

  2. 격리 수준(Isolation Level): 여러 트랜잭션이 동시에 처리될 때 다른 트랜잭션에서 변경 및 조회하는 데이터를 읽을 수 있도록 허용하거나 거부하는 정도를 나타낸다.

지속성(Durability)

지속성(Durability)은 트랜잭션이 성공적으로 커밋된 후, 해당 트랜잭션에 의해 생성 또는 수정된 데이터가 어떠한 상황에서도 보존되는 특징이다. 트랜잭션 수행 도중 시스템이 비정상적으로 종료되더라도, 시스템은 트랜젝션 로그(Transaction Log)를 통해 아직 커밋되지 않은 트랜잭션을 복구할 수 있다.

락(Lock)과 락킹 수준(Locking Level)

🔓락(Lock)의 종류

1. 공유 락(Shared Locks) || 읽기 락(READ Locks)

다른 트랜잭션이 데이터를 읽는 것은 허용하지만, 수정하는 것을 금지한다. 해당 락을 사용하는 트랜잭션이 모든 작업을 수행하였다면 공유 락은 해제됩니다.

# 트랜잭션을 시작합니다.
START TRANSACTION;

# SPARTA 테이블을 조회할 때, 해당 데이터들에 공유 락을 설정합니다.
SELECT * FROM SPARTA LOCK IN SHARE MODE;

2. 배타 락(Exclusive Locks) || 쓰기 락(WRITE Locks)

다른 트랜잭션이 데이터를 읽거나, 수정하는 것을 금지한다. 트랜잭션이 해당하는 데이터를 점유한 후 다른 트랜잭션이 해당 데이터에 접근 할 수 없도록 만든다.

# 트랜잭션을 시작합니다.
START TRANSACTION;

# SPARTA 테이블을 조회할 때, 해당 데이터들에 배타 락을 설정합니다.
SELECT * FROM SPARTA FOR UPDATE;

🔓락킹 수준(Locking Level)

잘못된 락 설정을 하게 될 경우 모든 API가 동작하지 않는 교착 상태(Dead Lock)가 발생하게 되어, 프로그램이 멈춰버리는 문제가 발생하게 될 수 있다. 교착 상태(Dead Lock)는 여러 테이블에 다른 작업이 처리되지 못하게 점유하고 있는 락(Lock)이 설정되어 있을 때, 다른 작업이 끝나는 것을 무한정 기다리는 현상이다. 따라서

1. 글로벌 락(Global Locks) | 데이터베이스 락(Database Locks)

가장 높은 수준의 락이다. 데이터베이스의 모든 테이블에 락을 걸어 현재 트랜잭션을 제외한 나머지 트랜잭션들이 모든 테이블을 사용할 수 없도록 만든다.

FLUSH TABLES WITH READ LOCK;

2. 테이블 락(Table Locks)

다른 사용자가 작업중인 테이블을 동시에 수정하지 못하도록 한다.

LOCK TABLES SPARTA READ;

3. 네임드 락(Named Locks)

테이블이나 테이블의 행과 같은 DB 오브젝트가 아닌, 특정한 문자열을 점유한다.

# 만약, 10초 동안 획득 하지 못한다면, NULL을 반환합니다.
SELECT GET_LOCK('sparta_name', 10);

4. 메타데이터 락(Metadata Locks)

다른 사용자가 작업중인 테이블의 동일한 행 및 동일한 데이터베이스의 객체를 동시에 수정하지 못하도록 한다.

# 테이블 구조를 변경할 때, MySQL은 내부적으로 메타데이터 락을 설정합니다.
ALTER TABLE SPARTA ADD COLUMN Age Int;

격리 수준(Isolation Level)

트랜잭션의 격리 수준 (Isolation Level)은 여러 트랜잭션이 동시에 처리될 때 다른 트랜잭션에서 변경 및 조회하는 데이터를 읽을 수 있도록 허용하거나 거부하는 것을 결정하는 정도를 말한다. 중요한 점은 ‘데이터의 일관성’과 ‘동시성 처리 성능’ 사이에서 균형을 잡는 것이다.

  1. READ UNCOMMITTED
    커밋 되지 않은 읽기(Uncommitted Read)를 허용하는 격리 수준. 가장 낮은 수준의 격리수준이며, 락을 걸지 않아 동시성이 높지만 일관성이 쉽게 깨질 수 있다.
  2. READ COMMITTED
    커밋 된 읽기(Committed Read)만을 허용하고, SELECT 문을 실행할 때 공유락을 건다. 다른 트랜잭션이 데이터를 수정하고 있는 중에는 데이터를 읽을 수 없어 커밋되지 않은 읽기 현상이 발생하지 않는다.
  3. REPEATABLE READ
    읽기를 마치더라도 공유락을 풀지 않으며, 트랜잭션이 완전히 종료될 때 까지 락을 유지한다. 공유락이 걸린 상태에서 데이터를 수정하는 것은 불가능하지만, 데이터를 삽입하는 것이 가능해진다. 그로 인해 팬텀 읽기(Phantom Read)가 발생할 수 있는 문제점이 있다.
  4. SERIALIZABLE
    데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 읽거나 삽입할 수 없고, 새로운 데이터를 추가하는 것 또한 불가능하다. 가장 높은 수준의 격리 수준이므로, 동시성이 떨어지는 문제점이 존재한다.

❓커밋되지 않은 읽기(Uncommitted Read)
다른 트랜잭션에 의해 작업 중인 데이터를 읽게 되는 현상다. 만약 커밋되지 않은 읽기가 발생할 경우, 의도치 않은 데이터를 참조하게 되어 데이터의 일관성이 깨지게 되는 상황이 발생한다.

❓팬텀 읽기(Phantom Read)
트랜잭션을 수행하던 중 다른 트랜잭션에 의해 삭제된 데이터를 팬텀행(Phantom Rows)이라고 한다. 여기서, 팬텀행에 해당하는 데이터를 읽는 것을 팬텀 읽기(Phantom Read)라고 부른다.

profile
황세민

0개의 댓글