#database, #transaction

Database Transaction

트랜잭션 이란?

SQL을 사용하여 INSERT나 UPDATE 명령을 사용할 때 COMMIT을 해주어야 실제 데이터베이스에 반영이 된다. 트랜잭션에 대하여 아직 깊게 공부하지 않은 사람이라면 ‘나는 COMMIT 한 적이 없는데 데이터베이스에 반영이 되었는데?‘라고 생각할 수도 있다. 이는 자동 커밋이라는 기능이 동작했기 때문이다.

그렇다면 트랜잭션이란 무엇일까? 트랜잭션은 데이터베이스 상태를 변환시키는 하나의 논리적 기능 수행 단위이다. 즉, 한 번에 수행되어야 할 일련의 연산을 말한다. 여기서 작업의 단위는 질의어 한 문장이 아니다. 질의어 명령문을 사람이 정하는 기준에 따라 정하는 것을 의미한다.

트랜잭션이 필요한 이유

회원의 등급을 업그레이드하는 작업을 진행한다고 생각해보자. 여러 명의 회원 등급을 업그레이드하는 도중에 시스템상의 문제로 작업이 마무리되지 못하였다. 이때 트랜잭션이 없었다면 어떤 회원의 등급은 업그레이드가 되고 어느 회원은 업그레이드가 되지 않는 문제가 발생하게 된다. 만약 이러한 일이 돈과 관련된 것이라면 더 심각한 문제가 될 수 있다. 트랜잭션으로 원하는 작업의 단위를 정하게 되면 작업을 수행하는 도중 문제가 발생하면 이전에 진행되었던 작업도 진행되지 않는다. 모든 작업을 안정적으로 끝마친 후에야 실제 데이터베이스에 반영이 되는 것이다. 즉, 회원 등급이 업그레이드가 돼야 할 회원 모두가 업그레이드가 되거나 모두 업그레이드가 안 된다는 뜻이다.

트랜잭션의 성질

위에서 봤던 트랜잭션의 성질을 흔히 ACID 로 표현한다. Atomicity(원자성), Consistency(일관성), Isolation(독립성), Durability(영속성)의 앞글자를 따 ACID로 트랜잭션의 성질을 표현한다. 그럼 ACID에 대하여 살펴보자

  • Atomicity(원자성)

    하나의 트랜잭션이 더 작게 나눌 수 없는 최소의 단위라는 뜻이다. 트랜잭션이 모두 반영되거나, 아니면 전혀 반영되지 않아야 하는 특징을 나타낸다. 계좌이체를 하는 경우를 생각해보자. 송금하는 도중에 문제가 발생하여 돈을 받아야 하는 사람에게 제대로 전달되지 않았다. 하지만 돈을 보내는 사람에게서는 이미 돈이 빠져나갔다면 큰 문제가 발생하게 될 것이다. 계좌이체 도중 문제가 발생하게 되면 송금하기 이전상태를 유지하게 되는 것을 원자성이라 볼 수 있다.

  • Consistency(일관성)

    일관성은 트랜잭션이 완료된 결괏값이 일관적인 데이터베이스 상태를 유지하는 것을 말한다. 사실 이 말만으로는 잘 이해가 되지 않는다. 예를 들면, 고객 정보가 담겨있는 데이터베이스에 새로운 고객이 등록되면 그 데이터베이스를 참조하는 다른 하위 계층의 데이터베이스도 같은 고객의 세부 정보를 가져와야 한다. 또는 모든 계좌의 돈은 0원 이상이어야 한다. 라는 무결성 제약이 있다면 이를 위반하는 트랜잭션은 모두 중단되어야 한다.

  • Isolation(독립성)

    트랜잭션이 수행되고 있을 때, 다른 트랜잭션의 연산작업이 중간에 끼어들어 기존 작업에 영향을 주지 못하도록 하는 것을 말한다. 독립성이 보장된다면 계좌 이체작업을 진행하고 있는 도중에 계좌의 잔액을 조회한다 거나 하는 작업을 동시에 수행할 수 없게 되는 것이다.

  • Durability(지속성)

    트랜잭션을 성공한 후 데이터베이스에 반영된 것은 영원히 반영되어야 한다는 것을 의미한다. 시스템에 문제가 발생하거나 종료되더라도 데이터베이스에 반영된 값은 그대로 유지되어야 한다. 은행에 시스템이 마비되었다가 재개되었을 때 계좌의 금액이 바뀌게 된다면 큰 문제가 될 것이다.

롤백과 커밋

트랜잭션을 사용해 데이터를 추가하다 에러가 발생하게 되면 어떻게 처리하게 될까? 이때 트랜잭션을 롤백하여 종료할 수 있다. 롤백을 진행하면 트랜잭션 내에서 행해진 모든 변경사항이 없었던 일이 된다. 트랜잭션 도중에 아무런 에러가 발생하지 않는다면 커밋을 하게 된다. 그러면 트랜잭션의 모든 변경사항이 데이터베이스에 반영되게 된다.

  • 롤백(Rollback)

    하나의 트랜잭션 처리가 비정상적으로 종료되면 트랜잭션의 원자성을 위해 해당 트랜잭션에서 작업한 모든 연산을 취소하여 실제 데이터베이스에 반영하지 않는다. 롤백하고 난 후에는 해당 트랜잭션을 재시작하거나 폐기하여야 한다.

  • 커밋(Commit)

    하나의 트랜잭션 작업이 정상적으로 끝마쳤을 때 커밋을 하게 된다. 커밋을 해야만 진짜 데이터베이스에 변경사항이 반영되는 것이다. 하나의 트랜잭션이 정상적으로 끝났다는 것을 알려주는 연산이다.

트랜잭션의 상태

  • Active(활동 상태)

    트랜잭션이 수행을 시작하여 현재 수행 중인 상태

  • Partially Committed(부분 완료 상태)

    마지막 연산이 실행된 직후의 상태. 연산은 모두 처리했지만, 데이터베이스에 반영되지 않았다.

  • Commited(완료 상태)

    트랜잭션이 성공적으로 완료되어 Commit을 한 상태

  • Failed(실패 상태)

    장애가 발생하여 트랜잭션이 중단된 상태

  • Aborted(철회 상태)

    수행에 실패하여 Rollback 연산을 실행한 상태

참고