📋DB 세션
- 사용자가 WAS나 DB 접근 툴 같은 클라이언트를 사용해서 데이터베이스 서버에 접근할 수 있는데, 클라이언트는 데이터베이스 서버에 연결을 요청하고, 커넥션을 맺게 됩니다.
- 이때, 데이터베이스 서버는 내부에 세션이라는 것을 만드는데, 앞으로 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행하게 됩니다.
- 클라이언트를 통해 SQL을 전달하면 현재 커넥션에 연결된 세션이 SQL을 실행합니다.
- 세션은 트랜잭션을 시작하고, 커밋이나 롤백을 통해 트랜잭션을 종료합니다. 그리고 이후에 다시 새로운 트랜잭션을 시작할 수 있습니다.
- 사용자가 커넥션을 닫거나, DBA가 세션을 강제로 종료하면 세션은 종료됩니다.
- 커넥션 풀이 10개의 커넥션을 생성하면, 세션도 10개가 만들어집니다.
📋DB 동시성 제어
- 여러 트랜잭션이 동시에 데이터베이스에 접근할 때, 데이터의 무결성과 일관성을 유지하기 위한 기법입니다.
- 트랜잭션 격리 수준 선택과 락을 사용하여 동시성을 제어할 수 있습니다.
📋갱신 손실 문제
- 두 개 이상의 트랜잭션이 같은 데이터를 동시에 수정할 때, 마지막으로 커밋된 트랜잭션의 변경 사항만 반영되고 나머지 트랜잭션의 변경 사항은 손실되는 상황을 말합니다.
📋트랜잭션
- 데이터베이스에서 하나의 논리적인 작업 단위를 의미합니다.
- 모든 작업이 성공할 경우,
Commit을 통해 데이터베이스에 정상 반영합니다.
- 작업 중 하나라도 실패할 경우,
Rollback을 통해 이전으로 되돌립니다.
✏️트랜잭션의 성질 ACID
원자성(Atomicity)
- 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 합니다.
일관성(Consistency)
- 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 합니다.
- 예를 들어, 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 합니다.
격리성(Isolation)
- 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리해야 합니다.
영속성(Durability)
- 트랜잭션을 성공적으로 끝내면, 그 결과가 항상 기록되어야 합니다.
✏️트랜잭션 격리 수준
- 트랜잭션 간의 격리 수준을 뜻합니다.
- 트랜잭션 간에 격리성을 완벽히 보장하려면 트랜잭션을 거의 순서대로 실행해야 하는데, 이렇게 하면 동시 처리 성능이 매우 나빠지게 됩니다.
- 이런 문제로 인해 ANSI 표준은 트랜잭션의 격리 수준을 4단계로 나누어 정의했습니다.
- 애플리케이션 설계자는 적절한 격리 수준을 선택하여 전체 처리량(throughput)과 데이터 일관성을 조율해야 합니다.
READ UNCOMMITTED(커밋되지 않은 읽기)
- 커밋 되지 않은 변경 데이터를 읽을 수 있습니다.
- 가장 낮은 격리 수준입니다.
READ COMMITTED(커밋된 읽기)
REPEATABLE READ(반복 가능한 읽기)
- 한 트랜잭션 내에서 동일한 결과를 보장합니다.
SERIALIZABLE(직렬화 기능)
- 트랜잭션이 순차적으로 처리됩니다.
- 이상 현상이 아예 발생하지 않는 완벽한 격리성을 제공하지만 동시 처리 성능이 매우 떨어집니다.
이상 현상
Dirty Read
- 변경 데이터를 읽었는데, 해당 트랜잭션이 롤백된 상황을 예로 들 수 있습니다.
Non-Repeatable Read
- 같은 데이터를 여러 번 읽을 때, 중간에 다른 트랜잭션이 해당 값을 변경하고 커밋하면, 동일한 데이터임에도 불구하고 이전과 다른 값이 반환되는 현상을 의미합니다.
Phantom Read
- 특정 조건으로 데이터 세트를 여러 번 조회할 때, 중간에 다른 트랜잭션에서 새로운 데이터를 추가하는 상황을 예로 들 수 있습니다.
- 결국 없던 데이터가 생기는 것을 의미합니다.
✏️Commit
- 트랜잭션 내의 모든 작업을 확정하여 데이터베이스에 영구적으로 반영하는 작업입니다.
✏️Rollback
- 트랜잭션 중 오류가 발생하거나 취소가 필요할 때, 트랜잭션 내의 모든 작업을 취소하여 원래 상태로 되돌리는 작업입니다.
✏️Auto Commit
Auto Commit을 true로 설정하면 쿼리 실행 직후에 자동으로 커밋을 호출하기 때문에 커밋이나 롤백을 직접 호출하지 않아도 되는 편리함이 있지만, 트랜잭션 기능을 제대로 사용할 수 없습니다.
Auto Commit은 false로 설정하면 커밋이나 롤백을 직접 호출해야 합니다.
- 보통
Auto Commit은 true가 기본 설정인 경우가 많기 때문에, 수동 커밋 모드로 설정하는 것을 트랜잭션을 시작한다고 표현할 수 있습니다.
📋DB 락
- 한 트랜잭션에서 접근하고 있는 데이터에 다른 트랜잭션이 접근하지 못하도록 잠그는 것을 의미합니다.
- 어떤 세션이 트랜잭션을 시작한 후, 데이터를 변경하고 싶다면 우선 락을 획득해야 합니다.
- 만약 이미 다른 트랜잭션이 락을 획득해서 데이터를 변경하고 있다면, 락을 획득하기까지 대기하게 됩니다. 이때 특정 대기 시간을 초과하면 락 타임아웃 오류가 발생합니다.
✏️Write Lock(Exclusive Lock)
- Read 혹은 Write 할 때 사용합니다.
- 다른 트랜잭션이 같은 데이터를 Read 혹은 Write 하는 것을 허용하지 않습니다.
✏️Read Lock
- Read 할 때 사용합니다.
- 다른 트랜잭션이 같은 데이터를 Read 하는 것을 허용합니다.
✏️DB 데드락
- 두 개 이상의 트랜잭션이 서로 상대방이 보유한 락을 획득하려고 무한정 대기하는 상태를 의미합니다.
📋DB 회복
- DB에 장애가 발생했을 때, 데이터베이스를 원래의 일관성 있는 상태로 되돌리는 과정을 의미합니다.
- 회복은 트랜잭션 단위로 진행됩니다.
✏️REDO, UNDO
REDO
- 트랜잭션이 성공적으로 완료되어 커밋 내역이 있는 상황에서, 시스템 장애로 인해 데이터가 손실되었다면, 해당 트랜잭션의 변경 내용을 다시 적용하는 작업입니다.
UNDO
- 트랜잭션이 실패했거나 롤백할 필요가 있을 때, 변경된 데이터를 이전 상태로 되돌리는 작업입니다.
✏️체크포인트 회복 기법
- 일정 시간 간격으로 데이터베이스의 상태와 트랜잭션 로그 파일을 동기화하여, 데이터베이스의 현재 상태를 디스크에 저장합니다.
- 장애 발생 시, 체크포인트 이후의 데이터만 복구하면 됩니다.
- 체크포인트 이후, 커밋 내역이 있는 트랜잭션의 경우
REDO를 진행합니다.
- 체크포인트 이후, 커밋 내역이 없는 트랜잭션의 경우
UNDO를 진행합니다.
📋MySQL InnoDB의 기본 트랜잭션 격리 수준
- MySQL의 InnoDB는 표준 SQL 바탕으로 격리 수준을 정의했습니다.
REPEATABLE READ를 기본으로 사용합니다.
- RDBMS마다 제공하는 격리 수준이 다를 수 있으며, 같은 이름의 격리 수준이라도 동작 방식이 다를 수 있습니다. 따라서 사용하는 RDBMS의 격리 수준을 잘 파악하여 적절히 선택하는 것이 중요합니다.
✳️ 참고 자료
유튜브 쉬운코드 - Lock
유튜브 쉬운코드 - 트랜잭션 격리 수준
망나니개발자 - 트랜잭션 격리 수준