원자성 (Atomicity) : 한 트랜잭션 내에서 실행한 작업들은 하나의 작업으로 간주한다. 모두 성공 또는 모두 실패되어야 한다.
일관성 (Consistency) : 모든 트랜잭션은 일관성 있는 데이타베이스 상태를 유지한다. 이를테면 DB에서 정한 무결성 조건을 항상 만족.
격리성 (Isolation) : 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리 해야한다.
지속성 (Durability) : 트랜잭션을 성공적으로 마치면 그 결과가 항상 저장되어야 한다.
이 중 격리성(Isolation)에 대한 이슈가 있다.
격리성을 완벽히 보장하기 위해 모든 트랜잭션을 순차적으로 실행한다면 동시성 처리 이슈가 발생한다. 반대로 동시성을 높이기 위해 여러 트랜잭션을 병렬처리하게 되면 데이터의 무결성이 깨질 수 있다.
격리성과 동시성으로 부터 파생되는 문제점부터 살펴 보자.
2. 격리성 관련 문제점
(1) Dirty Read
한 트랜잭션(T1)이 데이타에 접근하여 값을 'A'에서 'B'로 변경했고 아직 커밋을 하지 않았을때, 다른 트랜잭션(T2)이 해당 데이타를 Read 하면?
T2가 읽은 데이타는 B가 될 것이다. 하지만 T1이 최종 커밋을 하지 않고 종료된다면, T2가 가진 데이타는 꼬이게 된다.
(2) Non-Repeatable Read
한 트랜잭션(T1)이 데이타를 Read 하고 있다. 이때 다른 트랜잭션(T2)가 데이타에 접근하여 값을 변경 또는, 데이타를 삭제하고 커밋을 때려버리면?
그 후 T1이 다시 해당 데이타를 Read하고자 하면 변경된 데이타 혹은 사라진 데이타를 찾게 된다.
(3) Phantom Read
트랜잭션(T1) 중에 특정 조건으로 데이타를 검색하여 결과를 얻었다. 이때 다른 트랜잭션(T2)가 접근해 해당 조건의 데이타 일부를 삭제 또는 추가 했을때, 아직 끝나지 않은 T1이 다시 한번 해당 조건으로 데이타를 조회 하면 T2에서 추가/삭제된 데이타가 함께 조회/누락 된다. 그리고 T2가 롤백을 하면? 데이타가 꼬인다
3. 트랜잭션 격리수준
위와 같은 문제들 때문에, ANSI표준에서 트랜잭션의 격리성과 동시 처리 성능 사이의 Trade-off를 두고 4단계 격리수준을 나누었다. 내려갈수록 격리 수준이 높아져서 언급된 이슈는 적게 발생하지만 동시 처리 성능은 떨어진다.
참고로, 트랜잭션이 발생하면 락(Lock)이 걸리는데, SELECT 시에는 공유 락, CREATE/INSERT/DELETE 시에는 배타적 락이 걸린다
(1) Read Uncommitted
한 트랜잭션에서 커밋하지 않은 데이타에 다른 트랜잭션이 접근 가능하다. 즉, 커밋하지 않은 데이타를 읽을 수 있다.
이 수준은 당연히 위에서 언급한 모든 문제에 대해 발생가능성이 존재한다. 대신, 동시 처리 성능은 가장 높다.
발생 문제점 : Dirty Read, Non-Repeatable Read, Phantom Read
(2) Read Committed
커밋이 완료된 데이타만 읽을 수 있다.
Dirty Read가 발생할 여지는 없으나, Read Uncommitted 수준보다 동시 처리 성능은 떨어진다. 대신 Non-Repeatable Read 및 Phantom Read는 발생 가능하다.데이타베이스들은 보통 Read Committed를 디폴트 수준으로 지정한다.
발생 문제점 : Non-Repeatable Read, Phantom Read
(3) Repeatable Read
트랜잭션 내에서 한번 조회한 데이타를 반복해서 조회해도 같은 데이타가 조회 된다
이는 개별 데이타 이슈인 Dirty Read나 Non-Repeatable Read는 발생하지 않지만, 결과 집합 자체가 달라지는 Phantom Read는 발생가능하다.
발생 문제점 : Phantom Read
(4) Serializable
가장 엄격한 격리 수준
위 3가지 문제점을 모두 커버 가능하다. 하지만 동시 처리 성능은 급격히 떨어질 수 있다.
'Development > DB, JPA' 카테고리의 다른 글
EntityManager 와 EntityManagerFactory (0) | 2017.03.12 |
---|---|
Persistence Context 영속성 컨텍스트 (0) | 2017.03.12 |
@MappedSuperclass 에 관하여 ... (0) | 2016.08.10 |
Lazy Exception 과 Hibernate.initialize() (0) | 2016.07.26 |
CASCADE, 영속성 전이 (0) | 2016.07.17 |