작지만 꾸준한 반복

Transaction 얕게 아는 체 하기 본문

카테고리 없음

Transaction 얕게 아는 체 하기

iamjooon2 2023. 6. 5. 20:59

무심결에 썼던 @Transactional, @Transactional(readonly = true) 옵션들을 생각하며, 트랜잭션을 제 언어로 정리해보려 합니다.

1. Transaction?
위키백과에서는 다음과 같이 이야기합니다.

*데이터베이스 트랜잭션(Database Transaction)은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다. 여기서 유사한 시스템이란 트랜잭션이 성공과 실패가 분명하고 상호 독립적이며, 일관되고 믿을 수 있는 시스템을 의미한다.

이론적으로 데이터베이스 시스템은 각각의 트랜잭션에 대해 원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 영구성(Durability)을 보장한다. 이 성질을 첫글자를 따 ACID라 부른다. 그러나, 실제로는 성능향상을 위해 이런 특성들이 종종 완화되곤 한다.
*

데이터베이스의 정보들을 안정적으로, 일관성있게 유지하게 하는, 더이상 나눌 수 없는 하나의 작업 단위라고 볼 수 있습니다.


그렇다면 ACID는 무엇일까요?

2. ACID?

A - Atomicity: 원자성

트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 것을 말합니다.

C - Consistency : 일관성

트랜잭션이 실행을 성공적으로 실행되면, 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 말합니다.

I - Isolation : 독립성
한 트랜잭션 수행시, 다른 트랜잭션의 연산이 개입할 수 없는 것을 말합니다.

D - Durabioity : 지속성
한번 수행된 트랜잭션은 영원히 반영되어야 한다는 것을 말합니다.

 

트랜잭션은 다음과 같은 과정으로 수행됩니다.

1. 한 단위의 트랜잭션 시작

2. 여러 쿼리들이 실행

3. 트랜잭션 커밋 (성공시, 실제 갱신 적용)

 

그렇다면, 여러 Transaction을 사용하며 발생할 수 있는 문제도 있을까요?

1. dirty-Read

다른 트랜잭션에서 처리하는 작업이 완료되지 않았는데도, 다른 트랜잭션에서 볼 수 있는 현상을 dirty read라고 합니다.

2. Non-Repeatble Read

한 트랜잭션이 같은 쿼리를 두 번 실행했을 때, 그 사이 다른 트랜잭션이 데이터를 건드리게 됨으로써 생기는 데이터 불일치 현상입니다.

3. Phantom Read

한 트랜잭션에서 일정 범위 레코드를 두 번 이상 읽을 때 다른 트랜잭션이 수행되며 발생하는 데이터 불일치 현상입니다.

 

그렇다면 이를 어떻게 해결할 수 있을까요?

Isolation을 활용할 수 있는데요

Isolation이란, Transaction에서 일관성이 없는 데이터를 허용하도록 하는 수준을 말합니다

 

- Default : DB 설정, 기본 격리 수준(기본 설정)

- 레벨 0 - READ_UNCOMMITED : 커밋되지 않은 데이터에 대하여 다른 트랜잭션이 읽는 것을 허용합니다

    이때, Dirty Read가 발생할 수 있습니다

- 레벨 1 - READ_COMMITTED : 커밋된 데이터에 읽기를 허용합니다.

    격리 레벨 1에서는 Dirty Read를 방지하기 위해, 트랜잭션이 커밋되어 확정된 데이터만 읽는 것을 허용합니다

- 레벨 2 - 동일 필드에 대해 다중 접근시, 모두 동일한 결과를 보장합니다.

    트랜잭션이 완료될 때까지, select 문장이 사용하는 모든 데이터에 대해, 여러개의 트랜잭션이 동시에 일기기 접근을 수행할 수 있도록 하는 잠금(shared lock)이 걸리므로, 다른 사용자는 그 영역에 해당하는 데이터에 대한 수정이 불가능합니다.

    선형 트랜잭션이 읽은 데이터는 트랜잭션 종료 전까지 후행 트랜잭션이 갱신/삭제가 불가능하므로, 일관성 있는 결과를 반환합니다.

- 레벨 3 - SERIALZIABLE : 가장 높은 격리수준이며, 성능 저하의 우려가 있습니다.

    데이터의 일관성 및 동시성을 위한 MVCC(Multi Version Concurrency Control, 다중 사용자 DB 성능을 위한 기술로, 데이터 조회시 LOCK을 하지 않고, 데이터 버전을 관리해 일관성 및 동시성을 높이는 기술)을 사용하지 않습니다.

    트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능합니다.

   앞서 나온 Phantom Read를 방지할 수 있으며, 격리 수준이 올라갈수록 성능 저하 우려가 있습니다.