동시성 문제란 여러 트랜젝션이 동시에 데이터 베이스에 접근할 때 생기는 문제.
ACID(Atomicity, Consistency, Isolation, Durabilty) 원칙을 지키기 위해 동시성을 관리해줘야 한다.
=>같은 파일을 접근하면서 문제가 생길 수 있기 때문에 신경써야 한다.
Dirty Read
한 트랜젝션이 데이터를 변경했으나 그 변경값을 확정하지 않은 상태에서 다른 트랜잭션이 그 값을 읽는 경우.
예를들어 A가 500만원을 출금함. 그 값을 update하고 select하는 와중에 오류가 나서 롤백이 되었음. 근데 은행원 B가 A의 은행 계좌를 보는데 update만 된 상태에서 다시 select해서 읽으면 잘못된 결과=더티한 결과를 읽은게 됨
Non-Repeatable Read
Phantom Read: 한 트랜잭션 내에서 두 번 이상 같은 데이터를 읽었을 때, 그 사이에 다른 트랜잭션에 의해 새로운 레코드가 추가되거나 삭제되어서 두 번째로 읽은 값에 새로운 레코드나 삭제된 레코드가 반영된 경우.
동시성 문제의 근본적인 해결방법은 가변데이터에 순차적으로 접근할 수 있는 방법을 구상하는 것.
UPDATE, INSTERT 작업이 발생할 때 해당 데이터에 대한 락이 걸릴 수 있음.
락은 동시에 수행되는 다른 트랜잭션들이 대기 상태에 놓이게 하며, 이로 인해 성능 저하가 일어날 수 있다.
CQRS: 조회(SELECT) 분리
분산락:
대충 레디스로 가능
쿼리가 느리다는건 대부분 대부분 조인 관계 때문!!!! -> 조인을 하지 않는다.
Read Uncommitted (읽기 미확정)
가장 낮은 격리 수준.
트랜잭션에서 변경된 데이터를 다른 트랜잭션이 커밋되지 않은 상태에서도 읽을 수 있습니다.
Dirty Read가 발생할 수 있습니다.
Read Committed (읽기 확정)
트랜잭션에서 변경된 데이터는 해당 트랜잭션이 커밋을 한 후에만 다른 트랜잭션에서 읽을 수 있습니다.
Dirty Read는 방지되지만, Non-Repeatable Read는 발생할 수 있습니다.
Repeatable Read (반복 읽기)
트랜잭션 동안 동일한 데이터를 여러 번 읽을 때 항상 동일한 결과를 보장합니다.
Dirty Read와 Non-Repeatable Read는 방지되지만, Phantom Read(같은 조건으로 여러 번 조회했을 때 결과 집합이 다르게 나타나는 현상)가 발생할 수 있습니다.
Serializable (직렬화 가능)
가장 높은 격리 수준.
트랜잭션들이 순차적으로 실행되도록 함으로써 동시성 문제를 완전히 방지합니다.
성능 저하가 발생할 수 있지만, Dirty Read, Non-Repeatable Read, Phantom Read 모두 방지됩니다.
트랜잭션 시작 전: A 계좌에는 1000달러, B 계좌에는 500달러가 있다고 가정합시다.
트랜잭션 동안: A 계좌에서 200달러를 빼서 B 계좌로 이체하려고 합니다.
트랜잭션 후의 예상 상태: A 계좌에는 800달러, B 계좌에는 700달러가 되어야 합니다.
이때 "일관성"이란, 트랜잭션 수행 후에도 모든 계좌의 잔액 합계가 변하지 않는 것 (여기서는 총 1500달러)을 의미합니다.
만약 트랜잭션 수행 후 A 계좌에는 800달러가 남아있지만, B 계좌의 잔액이 600달러라면, 총합이 1400달러로 일관성이 깨진 것입니다.