트랜잭션(Transaction)과 ACID

트랜잭션이란?

정보처리기사 데이터베이스 과목을 공부했거나, 웹 프레임워크(Spring, Express.js, Django 등)을 사용해 봤다면 트랜잭션이라는 용어는 무조건 들어보게 될 것이다. 그만큼 데이터베이스에서 트랜잭션이란 개념은 상당히 중요하다. 트랜잭션은 데이터베이스에서 하나의 논리적인 기능을 수행하기 위한 작업의 최소 단위를 의미한다. 데이터베이스에 접근하는 방법은 질의(Query) 이므로, 달리 말하자면 여러 개의 질의를 하나로 묶는 단위라고 볼 수도 있다.

트랜잭션은 데이터베이스의 무결성을 유지하기 위한 필수적인 개념 혹은 기능이다. 이런 무결성을 위한 트랜잭션의 특성을 ACID 특성이라고 하는데, 각각의 문자는

  • 원자성(Atomicity)
  • 일관성(Consistency)
  • 격리성(Isolation)
  • 지속성(Durability)

의 앞 글자에서 따온 것이다. 그렇다면 여기부터는 각각의 특성에 대해 파고들어 보자.

ACID 특성

원자성

"All or Nothing" 즉, 하나의 논리적인 단위로 묶인 모든 작업이 성공적으로 완료되어야만 데이터베이스에 반영된다는 특성이다. 만약 논리적인 단위로 묶인 작업 중에서 단 하나라도 실패한다면, 해당 작업은 실패한 것으로 간주한다.

예를 들어 A라는 사람이 B라는 사람의 계좌에 500만원을 입금하려고 한다고 생각해 보자. 그렇게 될 경우 다음의 로직대로 실행될 것이다.

  1. A의 계좌 정보를 찾는다
  2. A의 계좌에서 500만원을 차감한다
  3. B의 계좌 정보를 찾는다
  4. B의 계좌에 500만원을 추가한다

그런데, 4번의 과정에서 모종의 이유로 오류가 발생하여 A의 계좌 정보를 찾아 A의 계좌에서 500만원이 빠져나간 것만 실행에 성공했다고 가정해 보자. 이렇게 되면 차액인 500만원이 갑자기 허공으로 사라진 것이나 다름없게 되어버린다. 따라서 이런 일이 발생하지 않도록 도중에 오류가 발생해 작업이 실패하게 되면 모든 일이 없었던 시점으로 되돌려야 문제가 발생하지 않는다. 이것을 데이터베이스 에서는 Commit과 Rollback이라는 명령어를 이용해 처리한다. 모든 작업이 정상적으로 완료 되었으면 Commit 명령어를 이용해 확정하고, 도중에 실패한 작업이 있으면 Rollback 명령어를 이용해 모든 것을 되돌려 놓는다.

일관성

트랜잭션이 성공적으로 반영된 데이터베이스의 상태는 항상 일관성을 유지해야 한다는 특성이다. 여기서 말하는 일관성이란 데이터베이스의 제약이나 규칙을 준수하는 것을 의미한다.

예를 들어 계좌의 잔액 컬럼에는 항상 자연수만 들어가야 한다는 제약조건이 있다고 가정해 보자. 그렇다면 이 컬럼에는 당연히 문자열이 들어가거나 음수가 들어갈 수 없다. 만약 이런 값이 해당 컬럼에 들어온다면, 데이터베이스는 그 즉시 트랜잭션을 종료시켜 버린다.

격리성

격리성은 하나의 트랜잭션이 실행중인 테이블에 다른 연산 작업이나 트랜잭션이 끼어들 수 없음을 보장하는 특성이다. 이 특성 덕분에 거의 동시에 여러 작업이 들어온다 하더라도 마치 순차적으로 처리하는 것처럼 보이게 한다.

그러나, 실제로 이 격리성이라는 특성을 철저하게 준수하게 되면 데이터베이스에 심각한 성능 저하를 일으킬 수도 있다. 그래서 데이터베이스에서는 데이터 정합성과 성능을 저울질할 수 있는 여러 수준의 격리성 단계를 지원하는 경우가 많다. (격리성 단계의 종류에 대해서는 여기서 다루지 않겠다.)

지속성

성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다는 것을 의미한다. 이는 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함을 의미한다. 데이터베이스는 이를 위해 체크섬, 저널링, 롤백 등의 기능을 제공한다.


정리하며

이번에는 데이터베이스의 트랜잭션과 ACID 특성에 대해 다루어 보았다. 데이터베이스의 트랜잭션과 ACID 특성은 정보처리기사의 데이터베이스 챕터에서 100% 나오는 개념이라고 생각해도 되니, 정보처리기사를 준비하거나 IT 업계에 취업할 생각이 있다면 반드시 알아두는게 좋다.