미루고 미루던 트랜잭션 정리하기 👊
예지니어스 테코톡을 보고 정리했습니다. 👋
여러 개의 Query가 하나의 로직으로 처리되는 것을 보장하기 위해
(예) 계좌입출금 (A가 B에게 10000원 입금한다.)
다른 트랜잭션과 변경된 상태를 공유할 것인가?
트랜잭션의 격리성과 동시처리를 기준으로 4가지 레벨이 존재한다.
트랜잭션에는 4가지 속성(ACID)가 있는데, 이 중 Isolation(독립,격리)가 성능 문제를 유발한다. 그래서 4가지 선택지를 제공하는 것이다. 격리성을 강화하고 (데이터 정확성을 보장) 성능을 낮추거나, 격리성이 떨어지되 성능을 높이거나 할 수 있는 것이다.
Atomicity (원자성)
트랜잭션 내부 작업이 모두 반영되거나 (commit) 모두 반영되지 않거나 (rollback)
Consistency (일관성)
DB 제약 조건에 맞는 일관성을 가진다.
Isolation (독립성)
각 트랜잭션은 독립적으로 운영된다.
A 트랜잭션 작업 도중 B 트랜잭션이 끼어들면 안된다
Durability (지속성)
트랜잭션을 성공적으로 마치면 (commit) 데이터는 저장된다.
성능 : READ-UNCOMMITTED > READ-COMMITTED > REPEATABLE-READ > Serializable
격리 수준 (데이터 정확성) : Serializable > REPEATABLE-READ > READ-COMMITTED > READ-UNCOMMITTED
commit되지 않은 변경사항도 다른 트랜잭션에서 사용할 수 있다.
발생 문제점 : Dirty Read, Non-Repeatable Read, Phantom Read
읽은 데이터가 정확하지 않을 수 있다.
commit된 변경사항을 다른 트랜잭션에서 사용할 수 있다.
발생 문제점 : Non-Repeatable Read, Phantom Read
언뜻보면 문제가 없을 것 같지만, A 트랜잭션과 B 트랜잭션이 교차되어 동작할 때를 생각하면 문제가 있다.
반복해서 읽었을 때 다른 데이터를 조회할 수 있다. (반복해서 조회하면 안된다.)
반복해서 읽어도 같은 데이터를 조회할 수 있다.
발생 문제점 : Phantom Read
1. 다른 트랜잭션을 고려하지 않고 commit 할 수 있다.
2. 대신 commit 이전 값이 undo 공간에 있고, commit 된 값이 아닌 undo 공간에 있는 데이터를 읽게 한다.
팬텀 리드 : 없었던 row가 나타나는 것
이렇게 데이터가 있는 상태
whyrano..팬텀 리드 문제가 발생하려면 두번째 select 에서 타미1, 타미2 모두 조회되야 되는 것 아닐까???!🤔🤔🤔🤔
MySQL에서는 팬텀 리드를 알아서 막아준다.
원래 같으면 팬텀 리드가 발생하여 타미1,타미2 모두 조회되어야 한다.
MySQL에서 팬텀리드를 방지하여 insert한 데이터가 보이지 않는다.
하지만 중복으로 insert는 안된다. 그 존재는 알고 있다는 의미이다.
격리성을 완죠니 보장한다.
A 트랜잭션에서 해당 테이블을 조회했을 때, B 트랜잭션은 데이터 수정/추가/삭제를 할 수 없다.
조회는 가능 가능
Serializable 아예 데이터 변경이 불가능한 것에 비해,
SNAPSHOT은 변경을 tempDB에 넣어둔 후 원래 트랜잭션이 끝나면 반영해준다.
트랜잭션 격리 레벨이 서로 교차할 때 (다를 때)에는 어떻게 되는가
우리 프로젝트에 적합한 격리 레벨은?
트랜잭션과 lock