siino's 개발톡

트랜잭션과 이상 현상을 직접 확인해보자! 본문

데이터베이스

트랜잭션과 이상 현상을 직접 확인해보자!

siino 2024. 2. 1. 19:12

데이터베이스에서 중요하다고 생각되는 개념인 트랜잭션과 동시성 문제에 대해서 알아보겠습니다.

트랜잭션이란?

논리적으로 나눠질 수 없는 최소한의 논리적 작업 단위입니다.

Spring Framework를 사용한다면 @Transactional로서 명시할 수 있고, START TRANSACTION, BEGIN등과 같은 키워드를 통해서 DB에서 명시할 수 있습니다.

 

트랜잭션의 특징 4가지 , ACID

Atomicity(원자성): All or Nothing에 대한 특징, 트랜잭션의 작업이 모두 성공적으로 처리되거나, 하나라도 실패한다면 전체가 실패해야 함을 의미합니다.

Consistency(일관성): 데이터베이스의 무결성 조건을 위반하지 않아야 한다. Table의 제약조건을 위반하지 않는다.

Isolation(독립성): 여러 트랜잭션이 동작해도 각각의 트랜잭션은 혼자 실행되는 것처럼 동작해야한다.

Durability(영속성): 트랜잭션이 Commit되었다면 그 데이터는 영구적으로 DB에 반영되야한다.

 

트랜잭션의 Isolation을 보장하기 위해서는?

데이터베이스 시스템이 다수의 트랜잭션이 동시에 수행될 때 발생할 수 있는 데이터 불일치 문제를 관리해야 합니다.

이를 위해 DBMS별 다양한 격리 수준(Isolation Level)을 제공하여 개발자가 애플리케이션의 요구사항에 맞게 격리 수준을 설정할 수 있게 합니다.

 

격리수준

READ UNCOMMITTED: 커밋되지 않은 데이터를 다른 트랜잭션에서 접근할 수 있다. (DIRTY READ문제)

READ COMMITTED: COMMIT된 데이터에 다른 트랜잭션이 접근할 수 있다.(UNREPEATABLE READ문제)

REPEATABLE READ: Mysql의 default level 동일 트랜잭션 내 일관성을 보장한다.(PHANTOM READ 문제)

SERIALIZE: 가장 강력한 LEVEL, 어떤 이상현상이라도 발생하지 않는다.

직접 각 이상현상을 확인해보자!

 

직접 제 PC의 isolation level을 확인해봤습니다.

show variables like 'transaction_isolation'; 의 명령어를 사용합니다.

 

한번 격리수준을 변경하면서 각각의 이상현상을 확인해보겠습니다.

준비물로는  2개의 mysql shell환경만 있으면 충분합니다.

 

이상현상을 탐지할 shell을 A shell

다른 트랜잭션을 실행시킬 shell을 B shell이라고 명시하며 각각의 이상현상을 확인해보겠습니다.

 

Dirty Read확인하기

1. 먼저 Ashell과 Bshell 모두 격리 수준을 READ UNCOMMITTED로 변경해줍니다.

 

2. Ashell에서 데이터를 update하고 아직 commit을 안했는데 Bshell에서 확인할 수 있습니다.

아직COMMIT하기도 전인데 다른 connection의 shell에서 변경된 모습을 확인할 수 있는 모습..

롤백을 하면 NAME 값이 원래대로 돌아갑니다.

 

un-repeatable Read확인하기

이번에는 격리 수준을 ReadCommitted로 변경해 준 후, 

Ashell에서는 id가 1인 레코드를 두번읽어보겠습니다.

이 사이에 Bshell에서는 name update가 일어납니다.

 

Ashell에서 첫번째 조회는 name이 NULL로 확인되지만, Ashell의 두 번재 조회에서는 name이 HONG GIL DONG으로 조회됨을 확인할 수 있습니다.

같은 데이터에 대해서 한 트랜잭션이 두번의 조회를 할때 결과값이 달라지는 이상현상 non repeatable read입니다.

 

마지막, Phantom Read 확인하기.

현재의 테이블은 아래 사진과 같습니다.

같은 방법으로 각각의 shell의 격리수준을 Repeatable read로 변경해준 후,

Bshell에서 해당 테이블에 대해 insert를 진행

 

하지만 Ashell에서는 Phantom Read가 조회되지 않는데..

 

MySQL의 REPEATABLE READ에서는 PHANTOM READ가 나타나지 않아서 찾아보니 MVCC로 인해서 나타나지 않는다고 합니다.^^

(잘못된 현상 아님!)

A의 트랜잭션을 COMMIT한 이후에나 PHANTOM!!을 볼 수 있었습니다. (이는 mysql InnoDB의 MVCC덕분이라고 하네요)

 

아직 트랜잭션과 동시성문제에 대해서 다룰 내용이 많지만 글이 너무 장황해질것같아

다음 글에서 작성하겠습니다!

 

'데이터베이스' 카테고리의 다른 글

[DB]트랜잭션/Lock/MVCC 정리  (1) 2024.02.05