레퍼런스
https://www.youtube.com/watch?v=e9PC0sroCzc&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9CTech
https://victorydntmd.tistory.com/129
여러 쿼리 작업 수행의 논리적 단위
트랜잭션이 필요한 이유
A 유저의 계좌에서 1000원을 출금하여
B 유저의 계좌로 1000원을 입금하는 로직이 있다고 가정해보자
만약 A유저에서 1000원을 출금하고 B 유저의 계좌로 1000원을 입금하는 과정에서 에러가 발생하여 입금이 되지 못했을 경우 중대한 오류가 발생하게 된다.
이를 방지하기 위해 반드시 수행되야하는 작업의 단위를 트랜잭션으로 묶어 실행하는 것이다.
트랜잭션으로 묶인 작업 단위에서 에러가 발생하면 중간 쿼리는 DB에 반영되지 않게 되어 돈이 유실되는 중대한 문제는 발생하지 않는다.
commit : 트랜잭션이 성공적으로 완료도면 DB에 최종적으로 반영하는 연산
rollback : 트랜잭션이 실행되는 도중 실패하게 되면 트랜잭션 수행 전 상태로 복구하는 연산
예를 들어 Integer 타입만 들어올 수 있는 열에 String 값이 들어오지 못하게 하는것을 의미한다.
Isolation 성질은 하나의 트랜잭션이 수행시 다른 트랜잭션이 이를 간섭하지 못하도록 하는 성질이다.
프로세스 하나만 DB에 접근 가능하다면 이를 충족시키는건 어렵지 않겠지만 DB는 여러 자원들이 공유하는 자원이기 때문에 현실적으로 Isolation을 완벽하게 충족시키기 위해서는
한번에 하나씩의 트랜잭션을 실행시켜야 한다. 이는 심각한 성능 낭비로 이어져 성능을 위해서 어느정도 타협이 필요하다.
트랜잭션이 끝나지 않은 상황에도 각기 다른 트랜잭션이 변경된 내용을 조회할 수 있음.
하지만 위와 같이 아직 트랜잭션이 COMMIT되지 않았음에도 트랜잭션 도중 변경된 값을
트랜잭션 B에서 읽을 수 있는 Dirty Read 현상이 발생하게 된다.
트랜잭션이 완료되어 커밋된 데이터만 조회할 수 있음
대부분의 DBMS에서 기본모드로 채택하고 있다.
이 경우 DIRTY READ 문제는 발생하지 않지만 위 그림과 같이
트랜잭션 A가 트랜잭션 B보다 빨리 COMMIT 되면, 트랜잭션 B의 SELECT 값이 서로 달라지는
Non Repetable Read 문제가 발생한다.
한 트랜잭션이 조회중인 데이터는 트랜잭션 범위 내에서는 동일함을 보장한다.
선행 트랜잭션이 읽은 데이터는 후행 트랜잭션이 수정하거나 삭제할 수 없게 함으로써 이를 보장한다.
하지만 수정과 삭제가 안될 뿐이지 삽입연산은 되기 때문에 Phantom Read 문제가 발생한다.
트랜잭션들을 순차적으로 실행시켜 ACID를 엄격하게 지키는 방법
성능이 가장 안좋다.