CS

[DB] 트랜잭션과 ACID, 데이터의 무결성

  • -
트랜잭션과 무결성에 대해 공부한 내용을 정리한 글입니다.

 

트랜잭션 

트랜잭션은 데이터베이스 시스템에서 수행되는 작업의 단위를 말합니다. 예를 들어 정보를 변경하거나 정보를 삽입할 때 사용되는 여러개의 쿼리를 묶은 단위를 트랜잭션이라고 합니다. 마치 프로그래밍의 함수와도 같습니다.

 

우리가 트랜잭션을 알아야 하는 이유는 트랜잭션은 데이터베이스에서 데이터의 일관성과 무결성을 유지하는 데에 중요한 개념이기 때문입니다. 트랜잭션은 ACID 속성을 준수함으로써 데이터의 일관성과 무결성을 유지할 수 있습니다.

 

ACID 속성을 요약하자면 다음과 같습니다.

  1. 원자성 (Atomicity): 트랜잭션은 모두 실행되거나 모두 실행되지 않아야 합니다. 즉, 트랜잭션의 모든 작업이 성공하면 커밋되고, 하나라도 실패하면 롤백됩니다.
  2. 일관성 (Consistency): 트랜잭션이 실행된 후에도 데이터베이스는 일관된 상태여야 합니다. 즉, 트랜잭션이 유효한 논리적 상태에서만 작업을 수행해야 합니다.
  3. 독립성 (Isolation): 여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션은 다른 트랜잭션에 영향을 받지 않아야 합니다. 즉, 트랜잭션은 다른 트랜잭션의 작업을 볼 수 없어야 합니다.
  4. 지속성 (Durability): 트랜잭션이 성공적으로 완료된 후에는 해당 변경 사항이 영구적으로 저장되어야 합니다. 데이터베이스 시스템이 중단되거나 장애가 발생해도 변경 내용이 유지되어야 합니다.

이제 각 속성에 대해서 더 자세히 알아보겠습니다.

 

원자성(Atomicity)

원자성은 트랜잭션의 작업들이 모두 수행되었거나, 모두 수행되지 않았거나 두 가지 상태를 보장하는 특징입니다. 즉, 트랜잭션이 여러 단계로 이루어져 있더라도, 모든 작업이 성공적으로 완료되었을 때만 트랜잭션이 커밋되고, 그렇지 않으면 롤백됩니다. 이러한 접근 방식을 통해서 데이터베이스의 무결성을 보장하고, 데이터베이스 시스템이 예기치 않게 중단되거나 오류가 발생해도 데이터 일관성을 유지할 수 있습니다.

 

가령, 은행에서 계좌 이체를 수행하는 경우를 생각해보겠습니다. 이체 과정은 보내는 계좌에서 돈을 출금하고, 받는 계좌로 돈을 입금하는 두 가지 작업으로 구성될 수 있습니다. 원자성을 준수하는 경우, 이체 과정은 출금과 입금 중 하나라도 실패하면 전체 이체 과정이 롤백되어야 합니다. 즉, 돈을 출금하고는 있지만 받는 계좌로 입금이 이루어지지 않는 상황을 방지할 수 있습니다.

 

커밋과 롤백

원자성을 설명하면서 언급한 커밋과 롤백에 대해 조금 더 자세하게 알아보겠습니다.

  1. 커밋(Commit): 트랜잭션의 모든 작업이 성공적으로 완료되었고, 데이터베이스의 상태가 일관성을 유지하는 경우에 트랜잭션을 커밋합니다. 이 때, 트랜잭션이 완료되어 데이터베이스에 영구적으로 반영됩니다. 다시 말해, 커밋은 트랜잭션이 완전히 처리되었음을 나타내며, 트랜잭션의 변경 사항이 영구적으로 저장되는 시점입니다.
  2. 롤백(Rollback): 트랜잭션의 어떤 이유로 인해 실패하거나 취소해야 할 때 사용됩니다. 롤백은 트랜잭션을 이전 상태로 되돌리는 작업을 의미합니다. 즉, 트랜잭션 중간에 문제가 발생했거나 트랜잭션을 취소해야 할 경우에 사용됩니다. 롤백을 수행하면 트랜잭션에 의한 변경 사항이 취소되고, 데이터베이스는 이전 상태로 되돌아갑니다.

커밋과 롤백은 데이터베이스 시스템에서 데이터 일관성과 무결성을 보장하기 위해 중요한 동작입니다. 커밋은 트랜잭션이 안전하게 완료되었음을 보장하고, 롤백은 트랜잭션 처리 중에 발생할 수 있는 문제를 해결하고 데이터의 일관성을 유지하는 데 도움이 됩니다.

 

일관성(Consistency)

일관성은 허용된 방식으로만 데이터를 변경해야 하는 것입니다. 데이터베이스에 기록된 데이터가 여러 조건, 규칙에 따라 유효해야 하는 것을 "일관되다" 라고 표현합니다. 즉, 트랜잭션 과정 또는 성공 후에 데이터는 항상 조건이나 규칙에 따라야 한다는 것입니다.

 

트랜잭션이 데이터베이스를 변경할 때, 데이터베이스는 일관성을 유지하면서 변경 사항을 적용해야 합니다. 이것은 데이터베이스가 트랜잭션이 실행되는 동안 여러 제약 조건을 준수하고, 무결성 규칙을 준수하는 것을 의미합니다. 예를 들어, 트랜잭션에서 A계정에서 돈을 출금하고 B계정으로 입금하는 경우에는 A계정과 B계정의 잔액이 항상 일관된 상태를 유지해야 합니다.

 

격리성(Isolation)

격리성(Isolation)은 데이터베이스 트랜잭션의 중요한 특성 중 하나로, 동시에 실행되는 여러 트랜잭션들 사이에 상호 간섭을 방지하고 격리하는 것을 의미합니다. 즉, 격리성은 여러 트랜잭션이 동시에 실행될 때 각 트랜잭션이 다른 트랜잭션에 영향을 미치지 않도록 보장하는 것입니다.

 

격리성은 다음과 같은 문제를 방지하기 위해 중요합니다.

  1. Dirty Read(더티 리드): 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 변경 사항을 읽는 것을 말합니다. 이러한 상황에서는 다른 트랜잭션이 롤백되면, 읽은 데이터가 유효하지 않아 문제가 발생할 수 있습니다.
  2. Non-repeatable Read(반복되지 않는 읽기): 동일한 쿼리를 두 번 실행할 때, 두 번째 실행에서는 다른 결과가 나타나는 경우를 말합니다. 이는 다른 트랜잭션이 중간에 데이터를 변경했기 때문에 발생할 수 있습니다.
  3. Phantom Read(유령 읽기): 동일한 쿼리를 두 번 실행할 때, 두 번째 실행에서는 다른 데이터가 나타나는 경우를 말합니다. 이는 다른 트랜잭션이 중간에 데이터를 추가 또는 삭제했기 때문에 발생할 수 있습니다.

격리 수준

격리 수준(Isolation Level)은 데이터베이스에서 여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션이 서로 어떻게 격리되는지를 정의하는 개념입니다. 격리 수준은 트랜잭션 간에 발생할 수 있는 각종 문제를 제어하고 관리하기 위해 사용됩니다. 주요 격리 수준에는 다음과 같은 네 가지 수준이 있습니다

 

  1. Read Uncommitted
    • 가장 낮은 격리 수준으로, 트랜잭션 A가 변경 중인 데이터를 트랜잭션 B가 읽을 수 있습니다.
    • Dirty Read(더티 리드), Non-repeatable Read(반복되지 않는 읽기), Phantom Read(유령 읽기) 문제가 발생할 수 있습니다.
  2. Read Committed
    • 한 트랜잭션이 데이터를 변경한 후에만 다른 트랜잭션이 해당 변경 사항을 읽을 수 있습니다.
    • Dirty Read를 방지하지만, Non-repeatable Read와 Phantom Read는 여전히 발생할 수 있습니다.
  3. Repeatable Read
    • 트랜잭션이 읽은 데이터는 해당 트랜잭션이 완료될 때까지 다른 트랜잭션에 의해 변경되지 않습니다.
    • Non-repeatable Read를 방지하지만, Phantom Read는 여전히 발생할 수 있습니다.
    • MySQL8.0, PostgreSQL, SQL Server, Oracle에서 기본값으로 설정되어 있습니다.
  4. Serializable
    • 가장 높은 격리 수준으로, 트랜잭션 간에 완전한 격리가 보장됩니다. 트랜잭션은 순차적으로 실행되는 것처럼 처리됩니다.
    • Dirty Read, Non-repeatable Read, Phantom Read 모두 방지됩니다.

격리 수준이 높을수록 데이터 일관성과 무결성을 유지하기 위한 비용이 높아질 수 있습니다. 따라서 적절한 격리 수준을 선택할 때는 데이터베이스의 특성과 성능 요구사항을 고려해야 합니다. 일반적으로, Serializable 격리 수준은 데이터 일관성이 매우 중요한 경우에 사용되며, Read Committed나 Repeatable Read는 보다 유연한 처리를 위해 선택될 수 있습니다.

 

지속성(Durablility)

지속성은 트랜잭션이 완료된 후에 데이터베이스의 상태가 영구적으로 유지되는 것을 보장하는 특성을 말합니다. 즉, 트랜잭션이 커밋되면 해당 변경 사항은 영구적으로 데이터베이스에 저장되고, 시스템이 중단되어도 유지됩니다.

 

이는 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함을 뜻하며, 데이터베이스는 이를 위해 체크섬, 저널링, 롤백 등의 기능을 제공합니다.

 

무결성

앞서 ACID 특성들을 소개하면서 데이터베이스의 무결성에 대해 아주 많이 언급했습니다. 

 

무결성이란 데이터의 정확성, 일관성, 유효성을 유지하는 것을 말하며, 무결성이 유지되어야 데이터베이스에 저장된 값과 그 값에 해당하는 현실 세계의 실제 값이 일치하는지에 대한 신뢰가 생깁니다.

 

무결성의 종류는 다음과 같습니다.

 

  1. 개체 무결성
    • 개체 무결성은 기본 키(primary key)를 사용하여 각 행(row)을 고유하게 식별할 수 있음을 보장합니다. 즉, 테이블의 기본 키는 NULL 값을 포함할 수 없고, 중복된 값을 가질 수 없습니다.
  2. 참조 무결성
    • 참조 무결성은 관계형 데이터베이스에서 관계(relation)가 유지되어야 함을 보장합니다. 즉, 외래 키(foreign key)가 참조하는 테이블의 기본 키(primary key)와 일치해야 합니다. 또한, 외래 키는 NULL이거나 유효한 값을 가져야 합니다.
  3. 고유 무결성
    • 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가집니다.
  4. NULL 무결성
    • 특정 속성 값에 NULL이 올 수 없다는 조건이 있는 경우 그 속성 값은 NULL이 될 수 없다는 제약 조건입니다.

부족한 글 읽어주셔서 감사합니다.


 
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.