본문 바로가기
데이터베이스

트랜잭션(Transaction)

by sepang 2022. 12. 10.

  트랙잭션이란 특정 단위로 처리되는 하나 이상의 SQL 작업의 시퀀스이다. 트랜잭션은 독립적으로 실행되어야 하고 만약 트랜잭션 수행이 실패하면 실행결과는 트랜잭션의 의도대로 완전히 반영되거나 아니면 전혀 반영되지 않아야 한다. 이것이 DB에서 중요한 이유는 동시성 때문이다. 물론 모든 DB 작업을 동시에 처리하면 성능적으로는 가장 좋겠지만 데이터의 안정성을 보장할 수 없다.

  예를 들면, 잔고가 10,000원인 계좌에 A가 1,000원을 입금하고 잔액을 확인하는 것과 B가 2,000원을 입금하고 잔액을 확인하는 작업이 동시에 이루어 졌다고 생각해보자. UPDATE 작업이 이루어지고 각자 잔액을 확인했을 때 A는 11,000이 아닌 13,000원을 조회하게 될 수가 있다. 만약 입금과 조회가 한 단위로 묶여 동시가 아닌 독립적으로 이루어졌다면 A, B 모두 의도한대로의 결과를 얻을 수 있었을 것이다. 그러므로 최대한 동시에 작업을 하되, 안정성이 보장되어야 할 때에는 순차적으로 작업을 수행할 필요가 있다.

 

커밋(commit) & 롤백(roll back)

  트랜잭션은 커밋되거나 롤백된다. 커밋은 변경된 데이터를 테이블에 영구적으로 반영하는 것이다. 커밋 이전에는 데이터의 변경사항이 메모리 버퍼에만 적용되지만, 커밋 이후에는 변경사항이 DB에 반영되며 이전 데이터는 영구적으로 사라진다.

  즉 커밋이전에는 변경 사항을 취소할 수가 있다는 것인데, 이를 롤백이라고 한다. 즉 데이터의 변경 사항이 취소되면서 변경 이전 상태로 되돌리는 것이다.

 

ACID

  트랙잭션은 4가지의 성질을 가지는데 각각 앞 글자를 따와 이를 ACID라고 한다.

 

Atomicity(원자성)

  트랜잭션이 DB에 모두 반영되거나 전혀 반영되지 않아야한다. 다르게 말하면 트랜잭션을 이루는 모든 명령은 완벽하게 수행되어야 하는데, 이 중 하나라도 오류가 발생하면 해당 트랜잭션의 명령들은 모두 취소되어야 한다.

 

Consistency(일관성)

  트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다. 즉 DB의 제약조건이 트랜잭션 시작 전이나 끝이나 모두 동일하게 만족하도록 보장해야 된다.

 

Isolation(독립성, 격리성)

 여러 개의 트랜잭션이 동시에 실행되는 경우 하나의 트랜잭션 연산에 다른 트랙잭션이 끼어들어서는 안된다. 즉 수행중인 트랜잭션은 완전히 완료될 때 까지는 다른 트랜잭션에서 수행결과를 참조할 수 없다. 하지만 이러한 고립 수준은 옵션으로 설정이 가능하다. 당연히 높을수록 데이터 일관성은 보장되지만 동시성은 하락하여 성능이 떨어질 수 있다.

이상현상

  고립 수준을 낮출수록 몇가지 이상현상이 발생할 수 있다.

  • Dirty Read: 아직 트랜잭션이 끝나지 않았는데 여기서 발생한 변경사항을 다른 트랜잭션에서 참조하는 경우
  • Non Repeatable Read: 어떤 트랜잭션에서 동일한 쿼리를 여러번 실행했는데 그 사이 다른 트랜잭션에서 수정이나 삭제 작업을 하여 동일한 쿼리임에도 다른 결과가 나오는 경우
  • Phantom Read: 어떤 트랜잭션에서 동일한 쿼리를 여러번 실행했는데 그 사이 다른 트랜잭션에서 추가 작업을 하여 동일한 쿼리임에도 다른 결과가 나오는 경우

고립수준

Read uncommitted

  가장 낮은 고립 수준이다. 각 트랙잭션에서의 변경 사항을 커밋&롤백 여부에 상관없이 다른 트랙잭션에서 참조할 수 있다. 당연히 정합성(데이터가 서로 모순 없이 일관되게 일치해야 함)이 떨어지므로 사용하지 않는게 좋다. 위 3가지의 이상현상이 모두 발생할 수 있다.

Read commited

  트랙잭션 수행 이후 commit된 데이터만 다른 트랜잭션에서 참조할 수 있다. DBMS에서 기본적으로 설정하는 고립수준이다. 커밋 전 데이터가 변경되었는데 다른 트랜잭션에서 이를 참조하려고 하면 이전 상태로 되돌려(undo) 변경 전의 정보를 참조하게끔 한다.

   당연히 Dirty Read는 발생하지 않겠지만 어떤 트랜잭션이 다른 트랜잭션 커밋 이전과 이후에 각각 결과를 조회했을 때 다른 결과를 반환할 수 있으므로 non repeatable read와 phantom read는 발생할 수 있다.

Repeatable read

  이론상 특정 트랜잭션에서 읽고 있는 데이터는 다른 트랜잭션에서 수정/삭제가 불가능하게 하는 것이다(삽입은 가능). 즉 자기보다 먼저 수행된 (커밋이 완료된)트랜잭션에서의 변경 사항만 읽을 수 있고, 늦게 수행된 트랜잭션은 커밋이 되었더라도 undo를 통해 변경된 것이 아닌 이전 데이터를 읽게끔한다. 이것이 가능한 것은 undo 영역이라는 곳에서 레코드를 백업해놓기 때문이다. 여기서는 non repeatable read 문제는 발생하지 않는다.

  하지만 count 연산을 할 때 어느 트랜잭션에서 삽입 작업을 해버리면 count의 결과는 다르게 나오는, 즉 phantom read가 발생할 수 있다.

Serialzable

  가장 단순하고 엄격한 격리 수준이다. 모든 작업이 동시에 이뤄지지 않고 직렬로 동작한다. 그러므로 특정 트랜잭션이 읽고 있는 데이터를 다른 트랜잭션에서 수정, 삭제, 삽입하는 것이 불가능하다. 모든 이상현상이 발생하지는 않겠지만 동시성이 떨어져 성능이 하락하여 잘 쓰이지 않는다.

 

Durability(영속성, 지속성)

  성공적으로 트랜잭션이 완료되면, 해당 결과는 시스템이 고장나도 영구적으로 반영되어야 한다.

'데이터베이스' 카테고리의 다른 글

Relational design theory  (0) 2022.11.03
SQL 3  (0) 2022.09.28
SQL 2  (0) 2022.09.23
SQL 1  (1) 2022.09.19
관계대수(Relational Algebra)  (0) 2022.09.14

댓글