[MariaDB] 트랜잭션, DB 트랜잭션 격리 수준

이지연·2025년 11월 24일

개요

데이터 무결성, 동시성, 일관성 보장에 핵심적인 개념인
트랜잭션(Transaction)의 기본 개념과 사용 패턴,
예외 처리 프로시저, 그리고 격리 수준(Isolation Level)까지
중요 내용을 치트시트 형식으로 정리해보겠다.


1. 트랜잭션 기본 개념 & 사용 패턴

  • 여러 개의 쿼리를 “하나의 작업 단위”로 묶어,
    전부 성공할 때만 COMMIT하고,
    하나라도 실패하면 전체를 ROLLBACK하는 메커니즘이다.
  • GUI 툴에서 보통 auto-commit이 켜져 있으면 각 쿼리마다 자동 커밋이 된다.
-- 트랜잭션용 컬럼 예시 (작성 글 수)
ALTER TABLE author ADD COLUMN post_count INT DEFAULT 0;

-- 기본 트랜잭션 흐름
START TRANSACTION;

-- 글쓴이의 글 개수 +1
UPDATE author
SET post_count = post_count + 1
WHERE id = 2;

-- post 에 글 생성 (FK 위반 시 실패)
INSERT INTO post (title, contents, author_id)
VALUES ('hello~', 'hello world', 2);

COMMIT;
  • 위 두 작업 중 하나라도 실패하면 전체가 롤백되어 데이터 불일치를 방지한다.
Datagrip 내 트랜잭션 모드가 자동으로 켜져있는 모습 확인

2. 프로시저 + 트랜잭션 + 예외 처리 패턴

MySQL 프로시저 안에서 트랜잭션 처리 중 예외 발생 시 롤백하도록 핸들러를 등록할 수 있다.

DELIMITER //

CREATE PROCEDURE transaction_test()
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;
    END;

    START TRANSACTION;

    UPDATE author
    SET post_count = post_count + 1
    WHERE id = 2;

    -- FK 위반 의도적 발생 (없는 author_id)
    INSERT INTO post (title, contents, author_id)
    VALUES ('프로시저 테스트', 'hello ...', 100);

    COMMIT;
END //

DELIMITER ;

-- 실행
CALL transaction_test();
  • 프로시저 내에서 에러가 발생하면 핸들러가 작동해 ROLLBACK 후 종료한다.
  • COMMIT 까지 도달하지 않으므로 데이터 정합성이 보장된다.

3. DB 트랜잭션 격리 수준(Isolation Level)

격리 수준설명문제 발생 가능성
READ UNCOMMITTED커밋되지 않은 데이터도 읽을 수 있음Dirty Read (더티 리드)
READ COMMITTED커밋된 데이터만 읽음Non-repeatable Read, Phantom Read
REPEATABLE READ같은 트랜잭션 내 동일 쿼리는 항상 같은 결과 반환 (기본값)Phantom Read, Lost Update
SERIALIZABLE트랜잭션들을 순차적으로 실행한 것과 같은 결과 보장동시성 낮음, 가장 안전
  • MariaDB/MySQL의 기본 격리 수준은 REPEATABLE READ이다.

4. READ UNCOMMITTED 실습 개념 (Dirty Read)


5. READ COMMITTED / REPEATABLE READ 실습 개념


두 세션에서 같은 데이터를 두 번 확인하는 상황에서 결과 달라짐


6. Lost Update 문제 & 배타락 해결 (SELECT ... FOR UPDATE)

  • lost update 문제 발생하는 상황
  • 배타락을 통해 lost update 문제를 해결한 상황

7. SERIALIZABLE 요약

  • 가장 높은 수준의 격리
  • 트랜잭션들이 완전히 직렬적으로 실행된 것과 같은 결과보장
  • 성능 저하 및 동시성 크게 떨어짐으로 꼭 필요한 경우에만 사용 권장

8. 한 줄 요약

  • 트랜잭션: 여러 쿼리를 하나의 논리적 단위로 묶어
    모두 성공하거나 모두 실패(ACID 원칙)하도록 보장하는 메커니즘
  • 주요 격리 수준
    • READ UNCOMMITTED: Dirty Read 허용
    • READ COMMITTED: 커밋된 데이터만 읽음
    • REPEATABLE READ (기본값): 트랜잭션내 스냅샷 일관성 보장
    • SERIALIZABLE: 완전 직렬화, 최고 안전
  • Lost Update 문제는 SELECT ... FOR UPDATE 배타적 잠금으로 방지

마치며

트랜잭션 단위에 대한 이해도를 갖고있으면 앞으로의 프로그래밍에도 많은 도움이 될 듯

profile
Eazy하게

2개의 댓글

comment-user-thumbnail
2025년 11월 25일

+25.11.24 강의 리뷰 추가

트랜잭션 정리

트랜잭션은 데이터베이스 상태를 변경하는 하나의 작업 단위로, 보통 하나 이상의 SQL 문 집합을 논리적인 작업 단위로 묶은 것입니다. 트랜잭션은 원자성(모두 성공하거나 모두 실패)이 보장되어야 하며, 작업의 최종 확정은 commit으로 하고, 문제가 생기면 rollback으로 되돌립니다. 실제로는 DB 내부에서 직접 커밋/롤백하기보다는 보통 Spring 등의 프로그램 단위(JPA 등)에서 트랜잭션이 관리되어, 프로그램 실행 도중 실패 시 롤백, 성공 시 커밋하도록 처리합니다.

동시성 이슈와 격리 수준

데이터베이스는 멀티스레드 환경에서 동시 작업을 처리하기 때문에 동시성 문제(예: Lost Update)가 발생할 수 있습니다. 이를 방지하기 위해 격리 수준(isolation level)을 설정하는데, MariaDB의 기본 격리 수준은 Repeatable Read 입니다. Lost Update 문제는 읽기 도중 다른 트랜잭션이 데이터를 수정하는 데서 발생하며, 이를 해결하기 위해 배타적 락(예: SELECT FOR UPDATE)을 걸어 특정 행에만 락을 걸기도 합니다.

격리 수준을 지나치게 높게 설정하는 것은 전체 DB 성능 저하로 이어지기 때문에 현실적인 해결책이 아니며, 락킹은 크게 배타락(Exclusive Lock)과 공유락(Shared Lock) 두 종류가 있습니다. 배타락은 데이터를 수정할 때, 공유락은 읽을 때 사용되어 동시 접근을 조절합니다.

답글 달기
comment-user-thumbnail
2025년 12월 11일

배타락?
그럼 오메가락, 알파락도 있나요?
아~~ 하하!
감사합니다

답글 달기