본문 바로가기
DB

[DB] 트랜잭션 정리 1편

by 개미가되고싶은사람 2024. 8. 6.

목차

    1. 트랜잭션이란?

    데이터를 데이터베이스에 저장하는 이유는 여러 가지가 있지만, 가장 일반적인 이유는 트랜잭션입니다. 트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서의 상호작용 단위를 의미합니다. 여기서 유사한 시스템이란 트랜잭션이 명확한 성공과 실패를 가지고 있으며, 서로 독립적이고 일관되며 신뢰할 수 있는 시스템을 말합니다.


    간단히 말해서, 트랜잭션이 안전하게 처리되도록 보장하는 것을 의미합니다. 그러나 트랜잭션을 안전하게 처리하기 위해서는 고려해야 할 사항이 많습니다. 은행 송금을 예로 들어 보겠습니다. A의 잔액을 5,000원 줄이고 B의 잔액을 5,000원 늘리는 두 가지 작업이 하나의 작업으로 수행되어야 합니다. 여기서 이 작업을 트랜잭션으로 생각하면, 잔액 감소와 잔액 증가 작업이 모두 성공해야 합니다. 만약 한 작업이 중간에 실패하면, 실행하기 전 상태로 되돌려야 합니다.

    이를 요약하면, 트랜잭션은 여러 단계로 구성될 수 있지만, 전체가 성공적으로 완료되거나 전혀 수행되지 않은 것처럼 동작해야 합니다. 이를 통해 데이터의 무결성과 일관성을 보장합니다.

     

    2. 트랜잭션의 4가지 특징 #ACID

    1. 원자성 (Atomicity)

    트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공 하거나 모두 실패해야 합니.

     

    2. 일관성 (Consistency)

    모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 합니다.

     

    3. 격리성 (Isolation)

    동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터
    를 수정하지 못하도록 해야 한다. 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation
    level)을 선택할 수 있습니다.

     

    4. 지속성 (Durability)

    트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 합니다. 중간에 시스템에 문제가 발생해도 데이
    터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 합니.

     

    완벽하게 트랜잭션 특성을 보장하려고 할 때 발생하는 문제 중 하나가 격리성 문제입니다. 격리성을 완전히 보장하기 위해서는 트랜잭션을 받은 순서대로 실행해야 합니다. 그러나 이렇게 하면 트랜잭션을 동시에 처리할 수 없어 성능이 매우 저하됩니다. 이러한 문제를 해결하기 위해 ANSI 표준에서는 트랜잭션의 격리 수준을 네 단계로 정의했습니다.

     

     

    트랜잭션의 격리 수준에 대해서 자세한 내용은 아래 블로그를 참고해주세요~~

    https://mangkyu.tistory.com/299

     

    [MySQL] 트랜잭션의 격리 수준(Isolation Level)에 대해 쉽고 완벽하게 이해하기

    이번에는 트랜잭션 격리 수준(Isolation Level)에 대해 알아보도록 하겠습니다. 아래의 내용은 RealMySQL과 MySQL 공식 문서 등을 참고하여 작성하였으며, 모든 내용은 InnoDB를 기준으로 설명합니다. 해

    mangkyu.tistory.com

     

     

    3. 트랜잭션 상태

    • 활동 상태 (active) : 초기 상태, 트랜잭션이 실행 중에 있는 상태
    • 부분 완료 상태 (partically committed) : 마지막 명령문이 실행된 후 상태지만, Commit 연산이 실행되기 직전의 상태
    • 완료 상태 (committed) : 트랜잭션이 성공적으로 완료된 후 Commit 연산을 실행한 상태
    • 실패 상태 (failed) : 트랜잭션에 오류가 발생하여 실행이 중단된 상태
    • 철회 상태 (aborted) : 트랜잭션이 취소되고 데이터베이스가 트랜잭션 시작 전 상태로 환원된 상태

     

     

    트랜잭션에 대해 더 자세히 이해하기 위해 데이터베이스 서버의 연결 구조와 DB 세션에 대해서 알아보겠습니다.

     

     

    4. 데이터베이스 연결 구조 및 세션 특징


    1. 사용자가 데이터베이스에 접근하려고 합니다.
    2. 사용자가 WAS 서버에 접근하면, 데이터베이스와 커넥션이 설정됩니다.
    3. 데이터베이스에서 DB 세션이 생성됩니다.
    4. 이 연결을 통해 이루어지는 모든 요청은 생성된 DB 세션을 통해 실행됩니다.

     

    세션은 트랜잭션을 시작하고, 이를 커밋하거나 롤백함으로써 트랜잭션을 종료합니다. 이후 새로운 트랜잭션을 다시 시작할 수 있습니다. 사용자가 연결을 닫거나 DBA가 세션을 강제로 종료하면 세션은 종료됩니다.

     

    ※ 참고로 커넥션 풀이 5개의 커넥션을 생성하면, 세션도 5개 만들어집니다.

     

     

     

     

    5. 세션 간 데이터 충돌이 일어난다면?

    필자는 해당 글을 작성하면서 의문이 들었습니다. 세션 A에서 기본키 값이 1이고 나머지 필드가 null인 데이터를 입력한 후 커밋하지 않은 상태에서, 세션 B에서 기본키 값이 1로 나머지 필드를 채운 데이터를 커밋하면 세션 A에서 데이터가 어떻게 나오는지 궁금해져서 한 번 알아봤습니다.

     

     

    해당 질문의 정답부터 말하면 트랜잭션 격리 수준에 따라 달라집니다.

     

    READ UNCOMMITTED(커밋되지 않은 데이터 읽기)

    • Session A: PRIMARY KEY가 1인 레코드의 값을 볼 수 있습니다.
    • Session B: PRIMARY KEY가 1인 레코드를 입력하고 커밋하면, Session A에서도 Session B의 데이터가 보일 수 있습니다.

    READ COMMITTED(커밋된 데이터 읽기)

    • Session A: 커밋되지 않은 데이터는 다른 세션에서 보이지 않습니다.
    • Session B: PRIMARY KEY가 1인 레코드를 입력하고 커밋하면, Session A에서는 여전히 NULL 값이 보입니다.
      Session A가 트랜잭션을 커밋하면, 개체 무결성 제약조건에 위배됩니다.

    REPEATABLE READ(반복 가능한 읽기)

    • Session A: 트랜잭션이 시작된 시점의 커밋된 데이터만 보입니다.
    • Session B: PRIMARY KEY가 1인 레코드를 입력하고 커밋하면, Session A의 트랜잭션이 종료되기 전까지는 Session A에 반영되지 않습니다. Session A가 트랜잭션을 커밋할 때 개체 무결성 제약조건에 위배됩니다.

    SERIALIZABLE(직렬화)

    • Session A: 트랜잭션이 시작된 시점의 커밋된 데이터만 보입니다.
    • Session B: PRIMARY KEY가 1인 레코드를 입력하고 커밋하려 하면, Session A의 트랜잭션이 종료될 때까지 대기하거나 오류가 발생할 수 있습니다.

    정리하자면  격리 수준이 높을수록 다른 세션의 커밋된 데이터를 바로 보지 못하게 되어 데이터 일관성을 보장할 수 있습니다.