woowacourse-study / 2022-cs-plant

cs 씨앗을 심기 위한 repository 입니다.
7 stars 1 forks source link

트랜잭션 격리 수준 #9

Open gudonghee2000 opened 2 years ago

gudonghee2000 commented 2 years ago

트랜잭션

트랜잭션은 DB의 상태를 변경하기 위해 수행하는 작업의 단위를 의미한다.

트랜잭션의 4가지 특징

  1. 원자성 트랜잭션은 모두 적용되거나 아예 적용되지 않아야 한다.
  2. 일관성 하나의 트랜잭션 안에서 작업 결과가 항상 같아야 한다.
  3. 독립성 트랜잭션이 다른 트랜잭션에게 관여하지 않아야 한다.
  4. 지속성 트랜잭션의 성공적으로 완료되면, 결과는 영원히 지속되어야 한다.

트랜잭션 격리 수준

동시에 여러개의 트랜잭션이 수행될 때, 하나의 트랜잭션이 다른 트랜잭션이 조회 혹은 수정하는 데이터를 볼 수 있도록 허용하는 수준을 의미한다.

트랜잭션 격리 수준의 4가지 종류

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

커밋되지 않았음에도 A 트랜잭션이 B 트랜잭션의 내용을 볼수 있다. 이러한 현상을 Dirty Read 라고한다.

Dirty Read 문제점

A 트랜잭션이 아무개를 Insert를 한 후, B 트랜잭션이 아무개를 select 했다고 생각해보자. 그런데 A 트랜잭션이 커밋되지 않고 롤백 되었다면, 실제 DB에는 아무개가 없는데 B 트랜잭션은 마치 DB에 아무개가 있는 것처럼 판단하게 된다.

그래서 READ UNCOMMITTED는 데이터 정합성이 매우 낮다. 하지만 DB 테이블 동시접근이 상당히 용이하기 때문에 동시성은 굉장히 높다.

READ COMMITTED(커밋된 읽기)

A 트랜잭션이 커밋되지 않았다면 아무개를 insert 해도 B 트랜잭션은 select시 아무개를 가지고 오지 않는다. 이후, A 트랜잭션이 커밋되면 B 트랜잭션은 select 시 아무개를 읽을 수 있다.

이것이 가능한 이유는 DB내부에 write작업이 들어오면 UNDO 라는 영역에 해당 레코드의 snapshot을 저장하기 때문이다. 그리고 select 시에 UNDO 영역에서 값을 읽어오다가 A 트랜잭션이 커밋되면 DB에서 값을 읽어온다.

그래서 DIrty Read가 가져오는 문제를 방지한다. 하지만, A 트랜잭션이 커밋 되기전에는 B 트랜잭션이 아무개를 찾지 못하다가 A 트랜잭션이 커밋되면 아무개를 찾아오는 ACID 중 일관성을 위반하는 문제를 가져온다.

결과적으로 READ UNCOMMITTED 보다는 데이터 정합성이 높지만 여전히 문제가 있다.

REPEATABLE READ(반복 가능한 읽기)

READ COMMITTED가 가져오는 NON-REPEATABLE READ문제를 해결한다. A 트랜잭션이 커밋되어도 B 트랜잭션은 UNDO 영역에서 아무개를 찾아오기 때문에 반복읽기가 가능하다. 하지만, 갑자기 아무개가 없어지거나 아무개와 다른 데이터도 같이 가져오는 PHANTOM READ 문제가 발생할수 있다.

PHANTOM READNON-REPEATABLE READ의 한 종류이다. 이러한 문제가 발생하는 이유는 A 트랜잭션이 아무개를 insert 한 이후에 강감찬도 insert하면 UNDO 영역에 반영되기 때문이다. 그래서 UNDO 영역을 기반으로 데이터를 찾아오는 B 트랜잭션은 PHANTOM READ 문제가 발생할수 있다.

SERIALIZABLE(직렬화 가능)

가장 높은 데이터 정합성을 보이지만 동시 접근이 거의 불가능 하다. A 트랜잭션이 접근하는 레코드에 락을 걸어 B 트랜잭션이 접근하지 못하게 막는것이다. 데이터 정합성은 상당히 높지만 동시성이 거의 없어 성능이 안좋다.

MySql이 REPEATABLE READ을 기본으로 지원하는 이유

데이터 정합성을 위해서는 SERIALIZABLE을 지원해야 할 것 같지만, MySql은 REPEATABLE READ을 디폴트로 지원한다. 그러한 이유는 Mysql이 REPEATABLE READ방식을 지원하는 방법 덕분이다. Mysql은 REPEATABLE READ 설정 시, 트랜잭션 마다 snapshot을 찍고 select 시 자신의 snapshot에서만 데이터를 읽어오게끔 한다. 그래서 PHANTOM READ 문제도 방지하고 데이터 정합성을 유지할수 있어 REPETABLE READ를 지원한다.


인터뷰 예상 질문

  1. 트랜잭션이란 무엇인가?
  2. 트랜잭션의 특징은?
  3. 트랜잭션의 격리수준은 무엇이 있을까?
  4. MYSQL이 REPEATABLE READ에서 PHANTOM READ를 어떻게 방지 했을까?
  5. 트랜잭션 격리수준마다 가져올수 있는 문제는 무엇이 있을까?