출처
김영한 강사님의 Spring DB 1편
📗 Transaction이란?
트랜잭션은 데이터베이스에서 하나의 거래를 안전하게 처리하도록 보장해주는 것을 뜻한다. 모든 작업이 성공해서 DB에 정상 반영하는 것을 Commit
이라 하고 작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 Rollback
이라 한다.
📄 ACID
트랜잭션의 ACID는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)을 보장해야 한다.
- 원자성(Atomicity)
트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 한다.
- 일관성(Consistency)
모든 트랜잭션은 일관성 있는 DB 상태를 유지해야 한다. 예를 들어 DB에 정한 무결성 제약 조건을 항상 만족해야한다.
- 격리성(Isolation)
동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level)
을 선택할 수 있다.
- 지속성(Durability)
트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템 문제가 발생해도 DB 로그등을 사용해서 성공한 내용을 복구해야 한다.
✅ 트랜잭션 격리 수준 Isolation level
- READ UNCOMMITED(커밋되지 않은 읽기)
커밋되지 않은 데이터를 읽어온다. 이를 Dirty Read
라 한다. 성능은 가장 좋지만 수정중인 데이터를 읽어오는 문제가 발생한다.
- READ COMMITED(커밋된 읽기)
커밋이 완료된 데이터만 읽어온다. 가장 많이 사용되는 수준이다. 하지만 동시에 다른 트랜잭션의 요청이 들어왔을 때 하나의 트랜잭션이 다른 트랜잭션 도중에 작업을 완료하여 이미 커밋이 되어버린 데이터라면 다른 트랜잭션에서 데이터를 select 하는 도중에 데이터가 변경되어 select가 되는 경우가 발생한다. 이러한 문제는 금전적인 처리에서 주로 발생하는 문제를 야기한다.
- REPEATABLE READ(반복 가능한 읽기)
트랜잭션마다 고유의 트랜잭션 ID값을 주어 자신의 트랜잭션 ID보다 작은 값에서 변경한 것만 읽게 된다. 또한 Undo공간에 백업해두고 실제 레코드값을 변경한다. 하지만 해당 격리 수준도 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안보였다 하는 현상 Phantom read
현상이 발생한다. 이를 방지하기 위해서는 쓰기 잠금을 걸어야 한다.
- SERIALIZABLE(직렬화 가능)
가장 안정적인 격리 수준. 트랜잭션이 사용중인 테이블의 모든 데이터에 다른 트랜잭션이 접근할 수 없도록 잠근다. 하지만 성능적으로 너무 느려 거의 사용하지 않는다.