포스트

MySQL 트랜잭션

MySQL 트랜잭션

트랜잭션이 필요한 이유

  • 데이터 변경 시 여러 작업을 논리적으로 쪼갤 수 없는 하나의 묶음으로 다루기 위해 트랜잭션이 필요
  • 트랜잭션은 전부 아니면 전무(All or Nothing) 원칙을 보장
  • 묶인 작업 중 하나라도 실패하면, 이전에 성공한 모든 작업을 자동으로 취소(원상 복구)하여 데이터의 일관성과 안정성을 지킴

커밋, 롤백

  • COMMIT: 트랜잭션 내의 모든 작업이 성공했을 때, 변경 사항을 영구적으로 저장
  • ROLLBACK: 문제가 발생했을 때, 트랜재션 내에서 실행한 모든 변경사항을 취소하고 시작 전 상태로 되돌림
  • MySQL은 기본적으로 autocommit 모드가 활성화 되어 있어 모든 SQL문이 즉시 COMMIT되므로 여러 문장을 묶으려면 START TRANSACTION을 명시적으로 사용해야 함
1
2
3
4
5
6
START TRANSACTION

-- INSERT, UPDATE, DELETE
  ...
  
COMMIT; -- or ROLLBACK;

트랜잭션 ACID 속성

  • 원자성(Atomicity): 트랜잭션은 전부 성공하거나 전부 실패해야 함
  • 일관성(Consistency): 트랜잭션 완료 휴에도 DB는 제약 조건 등 유효한 상태를 유지해야 함
  • 격리성(Isolation): 여러 트랜잭션이 동시에 실행될 때, 서로의 작업 중간 결과에 간섭할 수 없음
  • 지속성(Durability): 성공적으로 COMMIT된 트랜잭션의 결과는 시스템 장애가 발생해도 영구적으로 보존 됨

트랜잭션 격리 수준

동시성 문제

  • 더티 리드(Dirty Read): 한 트래잭션이 아직 COMMIT 하지 않은 수정 중인 데이터를 다른 트랜잭션이 읽는 것
  • 반복 불가능 읽기(Non-Repeatable Read): 한 트랜잭션 내에서 똑같은 SELECT 쿼리를 두 번 실행했는데, 그 사이에 다른 트랜잭션이 값을 수정하고 COMMIT하는 바람에 두 쿼리의 결과가 다르게 나오는 현상
  • 유령 읽기(Phantom Read): 한 트랜잭션 내에서 특정 범위의, 데이터를 두 번 읽었는데, 첫 번째 조회에서는 없었던 새로운 행이 두 번째 조회에서 나타나는 현상

4가지 표준 격리 수준

격리 수준Dirty ReadNon-Repeatable ReadPhantom Read
READ UNCOMMITTED발생발생발생
READ COMMITTED방지발생발생
REPEATABLE READ방지방지발생(알부 방지)
SERIALIZABLE방지방지방지
  • READ UNCOMMITTED: 거의 아무것도 막아주지 않는 가장 낮은 수준. 정합성 이슈가 많아 거의 사용되지 않음
  • READ COMMITTED: 덩티 리드를 방지. COMMIT 된 데이터만 읽을 수 있음
  • REPEATABLE READ
    • 한 트랜잭션 안에서는 데이터의 일관된 조회를 보장
    • MySQL의 InnoDB 스토리지 엔진이 사용하는 기본 격리 수준
  • SERIALIZABLE: 가장 엄격한 수준, 동시성 문제를 완벽하게 차단하지만, 트랜잭션을 거의 순서대로 실행시켜 동시 처리 성능이 가장 낮음

💡 MySQL InnoDB 특징

SQL 표준에 따르면 REPEATABLE READ 수준에서는 팬텀 리드가 발생할 수 있다고 정의됩니다.

MySQL의 InnoDB 엔진은 MVCC갭 락(Gap Lock)이라는 기술을 통해 REPEATABLE READ 수준에서도 대부분의 팬텀 리드가 발생하는 것을 막아줍니다.

이 때문에 InnoDB의 REPEATABLE READ는 표준의 SERIALIZABLE에 가까운 격리성을 제공합니다.(가깝다는 것이지 완벽한 것은 아님)

격리 수준 확인

1
SELECT @@transaction_isolation;

격리 수준 변경

  • 세션
1
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • 글로벌
1
2
SET
GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED

💡 실무 팁

특별한 이유가 없다면 MySQL의 기본 격리 수준인 REPEATABLE READ를 그대로 사용하는 것을 권장합니다.

참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.