관리 메뉴

Rootable의 개발일기

트랜잭션 본문

데이터베이스

트랜잭션

dev-rootable 2023. 8. 7. 14:47

 

<a href="https://kr.freepik.com/free-vector/locker_2900480.htm#query=lock&position=1&from_view=keyword&track=sph">작가 rawpixel.com</a> 출처 Freepik

 

📌 개요

 

트랜잭션은 ATM이나 데이터베이스 등의 시스템에서 더 이상 나눌 수 없는 업무 처리의 단위로, 하나 이상의 SQL문으로 구성된다. 여기서 나눌 수 없다는 것은
나눌 경우 시스템이나 데이터베이스에 심각한 오류를 초래할 수 있다는 의미이다. 이러한 개념의 기능을 데이터베이스에서 제공하는 것을 트랜잭션이라고 한다.

 

📌 트랜잭션 관리

 

트랜잭션은 하나의 논리적 작업 단위를 구성하는 하나 이상의 SQL문으로 구성되며, 모든 트랜잭션은 두 가지 상황으로 종료된다. 실행한 논리적 작업 단위 전체가 성공적으로 종료되면 그 트랜잭션은 영구적으로 데이터베이스에 저장된다. 이를 COMMIT이라 한다. 반면, SQL 실행 중 하나라도 정상적으로 종료되지 않으면 논리적인 작업 단위
전체를 이전 상황으로 ROLLBACK 한다.

 

다중 사용자 환경에서 트랜잭션은 동시성 제어(Concurrency control)고장 회복(Recovery) 기법에 의하여 관리된다. 동시성 제어는 한 사용자의 작업이
다른 사용자의 작업에 의해 방해받지 않도록 하는 조치들로 구성된다. 고장 회복은 데이터 처리 중 통신, 하드웨어, 소프트웨어 오류 발생 등 예기치 않은 예외 상황에 대한 조치들로 구성된다.

 

📌 트랜잭션 특성

 

🔸 원자성 (Atomicity)

 

모든 트랜잭션은 All or Nothing(완전히 수행하거나 전혀 수행하지 않은 상태로 회복되어야 함)이다.

 

🔸 일관성(Consistence)

 

트랜잭션을 실행하면 데이터베이스를 하나의 일관된 상태에서 또 다른 일관된 상태로 바뀐다.

 

즉, 트랜잭션은 데이터베이스의 일관성을 헤치지 않는다.

 

🔸 고립성(Isolation)

 

하나의 트랜잭션은 실행 완료될 때까지 현재 락(또는 세션)을 가진 사용자만이 변경 내용을 볼 수 있다.

 

🔸 영속성(Durability)

 

한 트랜잭션이 데이터베이스를 변경시키고 그 변경이 완료되면 결과는 이후의 어떠한 고장에도 손실되지 않아야 한다.

 

📌 트랜잭션 고립화 수준(Transaction Isolation Level)

 

트랜잭션 수준 읽기 일관성(Transaction-Level Read Consistency)은 트랜잭션이 시작된 시점을 기준으로 일관성 있게 데이터를 읽는 것을 말한다.

 

대부분 DBMS가 기본적으로 트랜잭션 수준 읽기 일관성을 보장하지 않으며, 트랜잭션 수준으로 읽기 일관성을 강화하려면 고립화 수준을 다음과 같이 높여 주어야 한다.

 

set transaction isolation level {read uncommitted|read committed|repeatable read|serializable};

 

🔎 레벨 0 (READ UNCOMMITTED)

 

트랜잭션에서 처리 중인 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용

 

✔ 발생 가능한 문제

 

  • Dirty Read
  • Non-Repeatable Read
  • Phantom Read

 

🔎 레벨 1 (READ COMMITTED)

 

대부분의 DBMS가 기본 모드로 채택하고 있는 일관성 모드로서, 트랜잭션이 커밋되어 확정된 데이터만 읽는 것을 허용

 

✔ 발생 가능한 문제

 

  • Non-Repeatable Read
  • Phantom Read

 

🔎 레벨 2 (REPEATABLE READ)

 

선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 변경하는 것을 불허함으로써 같은 데이터를 두 번 쿼리 했을 때 일관성 있는 결과를 리턴

 

✔ 발생 가능한 문제

 

  • Phantom Read

 

🔎 레벨 3 (SERIALIZABLE READ)

 

선행 트랜잭션이 읽은 데이터를 후행 트랜잭션이 변경하지 못할 뿐만 아니라 중간에 새로운 레코드를 삽입하는 것도 막아줌으로써 완벽한 읽기 일관성을 제공

 

참고로 Oracle은 Lock을 사용하지 않고 Undo 데이터를 이용해 Serializable Read를 구현한다.

 


💡 Dirty Read


특정 트랜잭션에 의해 데이터가 변경되었지만, 아직 커밋되지 않은 상황에서 다른 트랜잭션이 해당 변경 사항을 조회할 수 있는 문제

ex) 트랜잭션 A가 변경 후 commit 하지 않은 시점
      트랜잭션 B가 해당 데이터 읽음
      트랜잭션 A가 Rollback
      결과적으로 트랜잭션 B는 무효가 된 값을 다루게 됨

💡 Non-Repeatable Read

같은 트랜잭션 내에서 같은 데이터를 여러 번 조회했을 때 읽어 온 데이터가 다른 경우를 의미

💡 Phantom Read

Non-Repeatable Read의 한 종류로 조회해 온 결과의 행이 새로 생기거나 없어지는 현상

Reference:
https://hudi.blog/transaction-isolation-level/

 

데이터베이스 트랜잭션 격리 수준과 격리 수준에 따른 문제점

이 포스팅은 우아한테크코스 4기 2022 CS Plant 스터디에서 기술 면접을 대비하기 위해 작성되었습니다. 트랜잭션 격리 수준 복수개의 트랜잭션이 한번에 처리될 때, 특정 트랜잭션이 변경하거나

hudi.blog

 

📌 동시성 제어(Concurrency Control)

 

동시성 제어란 다수의 사용자가 데이터베이스에 동시에 접근하여 같은 데이터를 조회 또는 갱신을 할 때 데이터 일관성을 유지하기 위한 일련의 조치를 의미한다.

 

  • 데이터 동시성(Data Concurrency) : 각각의 사용자가 동시에 데이터에 접근
  • 데이터 일관성(Data Consistency) : 각각의 사용자가 자신의 트랜잭션이나 다른 사람의 트랜잭션에 변경된 내용을 포함하여 일관된 값을 본다는 의미

 

🔎 낙관적 동시성 제어(Optimistic Concurrency Control)

 

사용자들이 동시에 같은 데이터를 수정하지 않을 것이라고 가정한다. 따라서 데이터를 읽을 때는 락을 설정하지 않는다. 그러나 읽는 시점에 락을 사용하지 않지만 데이터를 수정하고자 하는 시점에 앞서 읽은 데이터가 다른 사용자에 의해 변경되었는지를 반드시 검사해야 한다.

 

✔ 특징

 

  • 잠김이 유지되는 시간이 매우 짧아져 동시성을 높이는 데 유리
  • 쇼핑몰과 같은 경합이 벌어지지 않는 업무에서 사용
  • 상품 조회 시점과 결제 시점에 가격이 다를 수 있으므로 반드시 데이터 수정 시 일관성 검사를 거쳐야만 한다.

 

🔎 비관적 동시성 제어(Pessimistic Concurrency Control)

 

사용자들이 같은 데이터를 동시에 수정할 것이라고 가정한다. 따라서 한 사용자가 데이터를 읽는 시점에 락을 걸고 조회 또는 갱신 처리가 완료될 때까지 유지한다.

 

✔ 특징

 

  • 한 사용자의 트랜잭션 완료 전까지 다른 사용자들이 수정할 수 없게 만들기 때문에 자칫 시스템 동시성을 심각하게 떨어뜨릴 수 있음
  • 데이터를 일일이 검사하지 않아도 됨
  • 만약 데이터 일관성이 중요한 업무(금융)라면 동시성이 저하되더라도 for update문으로 동시성을 개선하고 데이터 정합성도 높일 수 있다.

 

for update nowait ➡ Lock이 걸렸다면 대기 없이 예외를 던짐
for update wait ➡ Lock이 걸렸다면 3초간 대기하고 예외를 던짐

 

📌 Locking

 

트랜잭션의 동시성을 제어하기 위해 가장 많이 사용되는 기법으로 데이터 처리 과정에 있는 데이터를 읽지 못하게 하는 기법이다.

 

🔎 잠김 단위(Lock Granularity, Isolation level)

 

잠김 대상의 크기

 

✔ 잠김 단위가 크면

 

  • 동일한 잠김 대상에 동시 액세스할 확률이 높아져 충돌이 자주 발생
  • 관리 수월

 

✔ 잠김 단위가 작으면

 

  • 동일한 잠김 대상에 동시 액세스할 확률이 낮아져 충돌 횟수는 적어짐
  • 관리 대상의 수가 많아져 관리하기 어려움

 

🔎 유형

 

일반적으로 읽기 작업에는 공유 락을 필요로 하고 쓰기 작업에는 배타 락을 필요로 한다.

 

✔ 공유 락(Shared lock)

 

공유 락이 걸린 데이터에 대해서는 읽기 연산(SELECT)만 실행 가능하며, 쓰기 연산은 실행 불가하다. 공유 락이 걸린 데이터에 대해서 다른 트랜잭션도
똑같이 공유 락을 획득할 수 있으나, 배타 락은 획득할 수 없다.

 

공유 락을 사용하면, 조회한 데이터가 트랜잭션 내내 변경되지 않음을 보장한다.

 

✔ 배타 락(Exclusive lock)

 

데이터에 대해 배타 락을 획득한 트랜잭션은 읽기와 쓰기 연산을 모두 실행할 수 있다. 다른 트랜잭션은 배타 락이 걸린 데이터에 대해 읽기, 쓰기 작업 모두 수행할 수 없다. 즉, 배타 락이 걸려있다면 다른 트랜잭션은 공유 락, 배타 락 둘 다 획득할 수 없다. 배타 락을 획득한 트랜잭션은 해당 데이터에 대한 독점권을 갖는다.

 

Reference:

https://hudi.blog/mysql-8.0-shared-lock-and-exclusive-lock/

 

MySQL 8.0의 공유 락(Shared Lock)과 배타 락(Exclusive Lock)

락의 종류와 전략은 DBMS 벤더사마다 조금씩 다르다. 본 포스팅은 MySQL 8.0 InnoDB 기준으로 설명한다. DBMS에서 특정 데이터에 대한 동시 접근이 발생한 경우 일관성과 무결성 지키기 위해 해당 데이

hudi.blog

 

📌 고장 회복(Recovery)

 

트랜잭션 처리 중 장애가 발생했을 경우 데이터를 트랜잭션이 시작되기 이전 상태로 회복해야 한다. 이를 위해 데이터베이스는 로그를 사용해 Before Image로
UNDO(취소)를 실시하여 Rollback 처리한다.

 

Reference:

https://dataonair.or.kr/db-tech-reference/d-guide/da-guide/?mod=document&pageid=1&keyword=%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98&uid=302 

 

트랜잭션

트랜잭션은 ATM이나 데이터베이스 등의 시스템에서 더 이상 나눌 수 없는 업무 처리의 단위로, 하 나 이상의 SQL문으로 구성된다. 여기에서 더 이상 나눌 수 없다는 것은 실제로 나눌 수 없다기보

dataonair.or.kr

 

 

https://velog.io/@kw78999/DB-%EB%B9%84%EA%B4%80%EC%A0%81-vs-%EB%82%99%EA%B4%80%EC%A0%81-%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4

 

[DB] 비관적 vs 낙관적 동시성 제어

n-Tier구조가 지배적인 요즘은 DBMS의 트랜잭션 고립화 수준을 변경하는 방법을 사용하기가 어렵다.그리하여 개발자가 직접 동시성 제어를 개발한다.비관적 동시성 제어비관적 동시성 제어는 사

velog.io

 

'데이터베이스' 카테고리의 다른 글

데이터베이스 관리 대상  (0) 2023.09.08
인덱스(Index)  (0) 2023.09.07
데이터 무결성  (0) 2023.06.15
정규화(Normalization)  (0) 2023.06.14
E-R 모델  (0) 2023.06.13