인프런 김영한 - 스프링 DB 1 강의를 듣고 정리한 글 입니다.
목차
1. 트랜잭션이란
- 트랜잭션(Transaction)을 이름 그대로 번역하면 거래라는 뜻입니다.
- 이것을 풀어 이야기하면, 데이터베이스에서 트랜잭션은 하나의 거래를 안전하게 처리하도록 보장해주는 것을 뜻합니다.
모든 작업이 성공해서 데이터베이스에 정상 반영하는 것을 커밋(Commit)이라 하며,
작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 롤백(Rollback)이라고 합니다.
2. 트랜잭션 특징 (ACID)
트랜잭션은 ACID라 하는 4가지 특징을 보장해야합니다.
- 원자성 (Actomicity) : 트랜잭션 내에서 실행한 작업들은 마치 하나으 ㅣ작업인 것처럼 모두 성공하거나 모두 실패해야한다.
- 일관성 (Consistency) : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야한다.
- 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야한다.
- 격리성(Isolation) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.
- 예를들어 동시에 같은 데이터를 수정하지 못하도록 해야합니다.
- 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level)을 선택할 수 있습니다.
- 지속성 (Durability) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 합니다.
- 중간에 시스템에 문제가 발생해도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 합니다.
📌 트랜잭션은 원자성, 일관성, 지속성을 보장합니다.
하지만 격리성은 다릅니다. 트랜잭션간에 격리성을 완벽하게 보장하기위해서는 트랜잭션을 거의 순차적으로 실행해야만 합니다.
이렇게 된다면, 동시 처리의 성능이 매우 나빠지므로 ➡️ ANSI 표준은 트랜잯션의 격리 수준을 4단계로 나누어 정의했습니다.
3. 트랜잭션 격리수준
트랜잭션 격리 수준 - Isolation level
- READ UNCOMMITED (커밋되지 않은 읽기) - Dirty Read
- READ COMMITED (커밋된 읽기) -가장 많이 씀
- REPEATABLE READ (반복 가능한 읽기)
- SERIALIZABLE (직렬화 가능) - 거의 사용하지 않음
1) READ UNCOMMITED란
- 각 트랜잭션의 변경 내용이 Commit 이나 Rollback 여부에 상관없이 변경 중 다른 트랜잭션(작업) 에 그대로 보여지게 됩니다.
- Dirty Read - 다른트랜잭션이 수정중인 데이터를 볼 수 있는 현상을 말합니다.
- 더티리드 현상은, 데이터가 나타났다가 사라졌다하는 현상을 초래할 수 있기 때문에 개발자에게 혼란을 야기시킵니다.
2) READ COMMITED 란
- 많은 DB 에서 Default 로 사용하는 트랜잭션입니다.
- 어떠한 트랜잭션에서 데이터를 변경하더라도 커밋이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있기때문에 DirtyRead 가 발생하지 않습니다.
- 하지만 NON_REPEATABLE READ 부정합 문제가 존재합니다.
- 하나의 트랜잭션 내에서 동일한 Select 를 날렸을 때 항상 같은결과를 보장해야한다는 정합성
- A 트랜잭션 작업 중 다른 B 트랜잭션의 커밋이 완료되어 데이터가 변경되면, 변경된 데이터로 Select를 하기 때문에 조회결과가 중간에 바뀌어버립니다.
3) REPEATABLE READ 란
- 언두(Undo)영역에 백업된 이전 데이터를 통해 트랜잭션 내에서는 동일한 결과를 보여 주도록 보장하여 Non-Repeatable Read 문제를 해결합니다.
- 하지만 Phantom Read 문제가 발생합니다.
- Phantom read란, select ~ for update 와 같은 쓰기 잠금을 거는 경우 다른 트랜잭션에 수행한 변경 작업에 의해 레코드가 보였다가 안보였다가 하는 현상을 말합니다.
4) SERIALIZABLE 란
- 가장 단순하며 엄격한 격리 수준입니다.
- 그만큼 동시 처리 성능도 다른 트랜잭션 격리 수준보다 떨어집니다.
- 한 트랜잭션에서 읽고 쓰고있는 레코드는 다른트랜잭션에서 아예 접근할 수 없도록 Lock을 걸어버리는 격리 수준입니다.
- Serializable 에서는 모든 부정합 문제가 발생하지 않습니다.
4. 데이터베이스 연결 구조와 DB 세션
트랜잭션을 더 자세히 이해하기 위해 데이터베이스 서버 연결 구조와 DB 세션에 대해 알아봅니다,
- 사용자는 웹 어플리케이션 (WAS) 나 DB 접근 툴 같은 클라이언트를 사용하여 데이터베이스 서버에 접근할 수 있습니다.
- 클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게됩니다,
- 이때 데이터베이스 서버는 내부에 세션이라는 것을 만듭니다.
- 그리고 앞으로 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행합니다,
- 세션은 트랜잭션을 시작하고, 커밋 또는 롤백을 통해 트랜잭션을 종료합니다,
- 그리고 이후에 새로운 트랜잭션을 다시 시작할 수 있습니다.
- 사용자가 커넥션을 닫거나, 또는 DBA가 세션을 강제로 종료하면 세션은 종료됩니다.
5. 트랜잭션 정리
원자성
- 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 합니다.
- 트랜잭션의 원자성 덕분에 여러 SQL 명령어를 마치 하나의 작업인 것처럼 처리할 수 있습니다.
- 성공하면 한번에 반영하고, 중간에 실패해도 마치 하나의 작업을 되돌리는 것처럼 간단히 되돌릴 수 있습니다.
오토 커밋
- 만약 오토 커밋 모드로 동작하는데, 계좌이체 중간에 실패하면 어떻게 될까요?
- 쿼리를 하나 실행할 때 마다 바로바로 커밋이 되어버리기 때문에 데이터 정합성이 깨지게 됩니다.
트랜잭션 시작
- 따라서 이런 종류의 작업은 꼭 수동 커밋 모드를 사용해서 수동으로 커밋, 롤백 할 수 있도록 해야합니다.
- 보통 이렇게 자동 커밋모드에서 수동 커밋 모드로 전환하는 것을 트랜잭션의 시작이라 합니다.
'Spring > Spring 김영한' 카테고리의 다른 글
[Spring DB 1편] (2) 커넥션풀과 데이터소스 이해 (0) | 2022.09.30 |
---|---|
[Spring DB 1편] (1) Jdbc의 이해 (0) | 2022.09.08 |
[Spring 기본편] (2) Spring 컨테이너의 필요성 - 스프링 컨테이너란, Bean의 관리 (0) | 2022.05.14 |
[Spring 기본편] (1) 스프링이란 / 스프링과 객체 지향에 대하여 (0) | 2022.05.13 |