CS

[CS] DB - 트랜잭션과 격리성

육빔 2024. 9. 5. 19:15
728x90
반응형

DB를 공부하던 중 트랜잭션을 정확히 모르겠어서 공부하고 정리하고자 한다. 우선 트랜잭션을 왜 알아야하나? 며칠 전 내가 겪었던 일인데 맥도날드 앱에서 햄버거를 결제하던 중 네트워크 문제가 발생해서 카카오페이에서 돈만 빠져나가고 햄버거가 처리 안된 경우를 겪었었다. 여기서 만약 돈만 빠져나가고 햄버거가 처리가 안된다면 엄청난 문제가 발생할 것이다. 30분정도 지나니 트랜잭션 처리(아마)로 카카오페이에 돈이 다시 입금되는 것을 볼 수 있었다. 이러한 문제를 해결하기 위해 All Or Nothing 전략을 사용한다. 이 전략은 말 그대로 전부하거나 나무것도 하지 않거나 둘 중 하나만 하는 전략이다. 만약 중간에 에러가 발생하면 Rollback으로 Nothing을 취하게 된다.

 

트랜잭션(Transaction)은 4가지 주요 속성이 있다.

또한 데이터베이스에서 수행되는 작업의 단위이기도 하다. ACID 많이 들어봤을거다.

  1. 원자성(Atomicity): 트랜잭션 내의 모든 작업이 성공적으로 완료되거나, 아무 작업도 완료되지 않은 것처럼 취급됩니다. 즉, 작업이 중간에 실패하면 전체 트랜잭션이 롤백되어 이전 상태로 되돌아갑니다.
  2. 일관성(Consistency): 트랜잭션이 완료되면 데이터베이스가 일관된 상태를 유지해야 합니다. 데이터베이스의 규칙과 제약 조건이 항상 충족되어야 합니다.
  3. 격리성(Isolation): 트랜잭션 간의 상호작용을 최소화하여 각 트랜잭션이 독립적으로 실행되도록 보장합니다. 트랜잭션이 동시에 실행되더라도 서로의 결과를 방해하지 않아야 합니다.
  4. 지속성(Durability): 트랜잭션이 성공적으로 완료된 후, 그 결과는 영구적으로 데이터베이스에 저장됩니다. 시스템 충돌이나 오류가 발생하더라도 트랜잭션의 결과는 보존됩니다.

여기서 더 알면 좋을 것은 격리성이다. 각 트랜잭션의 접근 레벨이 있고 DB에 따라 설정 가능하다. 또한 이런 격리성으로 몇가지 문제가 발생할 수 있는데 아래를 보자.

 

1. Dirty Read (더티 리드)

정의: Dirty Read는 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 데이터를 읽는 상황을 말합니다. 만약 그 트랜잭션이 롤백된다면, 읽었던 데이터는 실제로는 유효하지 않게 됩니다.

 

쉽게 생각하면 위 예시에서 네트워크 문제로 인해 햄버거 주문이 처리되지 않았지만, 카카오페이에서는 돈이 이미 빠져나간 상태입니다. 만약 시스템이 이 상태에서 주문 처리 부분이 커밋되지 않은 상태로 다른 부분에서 읽어들이거나 참조하게 된다면, Dirty Read가 발생하는 갓이다.

 

2. Non-Repeatable Read (비 반복 읽기)

정의: Non-Repeatable Read는 같은 트랜잭션 내에서 동일한 데이터 항목을 두 번 읽었을 때, 두 번째 읽기에서 다른 값을 얻는 현상을 말합니다. 이는 다른 트랜잭션이 데이터를 수정했기 때문에 발생합니다.

 

만약 네트워크 문제로 인해 결제가 처리되지 않고 돈만 빠져나갔을 때, 나중에 결제 상태를 다시 확인할 때 데이터가 달라지는 것이다. 예를 들어, 처음에는 결제 완료 상태로 보였지만, 나중에 트랜잭션이 롤백되거나 수정되면서 결제 상태가 변경될 수 있는게 비 반복 읽기다.

3. Phantom Read (팬텀 리드)

정의: Phantom Read는 같은 쿼리를 실행했을 때, 다른 트랜잭션이 데이터베이스에 새로운 데이터 행을 삽입하거나 기존 데이터를 삭제함으로써, 결과 집합이 달라지는 현상입니다.

 

결제 실패 후 재시도 과정에서 주문이 다시 추가되거나 삭제되면, 같은 쿼리를 여러 번 실행할 때 결과가 달라지는 Phantom Read가 발생할 수 있습니다.

 

 

 

지정할 수 있는 격리 수준을 이제 알아보자.

 

 

  • Read Uncommitted (읽기 미완료, 미확정 읽기):
    • 가장 낮은 수준의 격리성으로, 다른 트랜잭션에서 커밋되지 않은 데이터를 읽을 수 있습니다.
    • 문제점: Dirty Read(더티 리드) 현상이 발생할 수 있습니다. 즉, 트랜잭션이 아직 커밋하지 않은 데이터를 다른 트랜잭션이 읽어오는 상황이 발생할 수 있습니다.
  • Read Committed (읽기 확정, 커밋된 읽기):
    • 트랜잭션이 다른 트랜잭션에서 커밋된 데이터만 읽을 수 있습니다.
    • 문제점: Non-Repeatable Read(비반복적 읽기) 문제가 발생할 수 있습니다. 동일한 트랜잭션 내에서 같은 데이터를 다시 읽을 때 다른 값으로 변경되어 있을 수 있습니다.
  • Repeatable Read (반복 가능 읽기):
    • 트랜잭션이 실행되는 동안 읽은 데이터가 변경되지 않도록 보장합니다.
    • 문제점: Phantom Read(팬텀 리드) 문제가 발생할 수 있습니다. 트랜잭션 내에서 쿼리 시 특정 조건을 만족하는 행이 없었지만, 나중에 동일한 조건으로 조회했을 때 새로운 행이 추가되어 있을 수 있습니다.
  • Serializable (직렬화 가능):
    • 가장 높은 수준의 격리성으로, 트랜잭션들이 순차적으로 실행되는 것처럼 동작합니다.
    • 모든 트랜잭션이 격리되어 실행되므로 Dirty Read, Non-Repeatable Read, Phantom Read 문제가 모두 방지됩니다.
    • 단점: 성능이 저하될 수 있습니다. 동시에 실행되는 트랜잭션 수가 크게 줄어들어 병목 현상이 발생할 수 있습니다.

 

728x90
반응형