Study 6화 - Transaction #1

yeolyeol·2024년 8월 19일
0

til

목록 보기
14/27
post-thumbnail

정리하기 전에

다음과 같은 상황이 있다고 가정해 보자.

  1. 매달 부모님께 생활비 30만원을 받는 아들이 있다.
  2. 이번 달에도 부모님께서 생활비를 주실 예정이다.
  3. 부모님께서 인터넷 뱅킹으로 아들에게 줄 30만원을 송금했다.
  4. 아들 통장에 30만원이 입금된 것을 확인하고 기분이 좋아진다.
  5. 하지만, 모종의 이유로 송금처리가 취소되며 원래 30만원을 송금하기 전 상태로 되돌아 갔다.
  6. 아들의 통장에는 30만원이 그대로 유지되고 있다.

만약 위와 같은 상황이 발생한다면, 치명적(?)인 돈 복사 결과가 나타난다.
은행 입장에서는 매우 치명적인 상황이며, 입금송금 두 과정 중 하나만 성공하면 안되는 것을 알 수 있다.

즉, 동시에 성공 또는 실패를 해야한다.
이 과정을 동시에 묵는 방법이 이번에 다룰 트랜잭션이다


트랜잭션

정의

더이상 분할이 불가능한 업무처리의 단위

분할이 불가능하다는 것은, 물리적으로 쪼갤 수 없는 것이 아닌 하나의 작업을 위해 논리적으로 분할될 수 없는 것을 뜻한다고 생각하면 이해가 쉽다.

즉, 한 번에 수행되어야 할 일련의 연산 모음이다.

왜 사용할까?

이유는 정리하기 전 예시를 들었던 것과 유사하다.

트랜잭션은 데이터베이스와 애플리케이션의 데이터 거래에 있어서 안전성을 확보하기 위해 사용한다.
즉, 트랜잭션이라는 작업 단위안에서는 수행에 대한 데이터의 안전성을 보장하기 위해 사용한다.

이후 여러 사용자가 동시에 접근할 때 이를 제어하기 위해도 사용한다.

ACID

RDBMS를 정리할 때에도 ACID를 다루었는데, 트랜잭션에서도 다시 ACID를 정리하게 되었다.

원자성(Atomicity)

트랜잭션이 데이터베이스에 모두 반영되던가, 아니면 전혀 반영되지 않아야 한다는 것.
트랜잭션은 사람이 설계한 논리적인 작업 단위로서, 일처리는 작업단위 별로 이루어 져야 사람이 다루는데 무리가 없다.
만약 트랜잭션 단위로 데이터가 처리되지 않는다면, 설계한 사람은 데이터 처리 시스템을 이해하기 힘들 뿐만 아니라, 오작동 했을시 원인을 찾기가 매우 힘들어질 것이다.

일관성(Consistency)

트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것.
트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트된 데이터베이스로 트랜잭션이 진행되는것이 아니라, 처음에 트랜잭션을 진행 하기 위해 참조한 데이터베이스로 진행된다.
이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것이다.

독립성(Isolation)

둘 이상의 트랜잭션이 동시에 실행 되고 있을 경우 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다는 점을 가리킨다.
즉, 하나의 특정 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.

영구성(Durability)

지속성은 트랜잭션이 성공적으로 완료됬을 경우, 결과는 영구적으로 반영되어야 한다는 점이다.

상태


트랜잭션의 연산 과정의 단계를 도식화한 것이다. 각 단계의 상세는 다음과 같다.

  • 활성(Active)
    트랜잭션이 정상적으로 실행 중인 상태

  • 부분 완료(Partially Committed)
    트랜잭션의 마지막까지 실행되었지만, Commit 연산이 실행되기 직전인 상태

  • 완료(Committed)
    트랜잭션이 성공적으로 마무리 되어 Commit 연산을 실행한 후의 상태
    트랜잭션이 완료되면 데이터가 DB에 영구적으로 반영됨.

  • 실패(Failed)
    트랜잭션 실행에 오류가 발생하여 중단된 상태

  • 철회(Aborted)
    트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태.

Commit

Commit이란, 모든 작업들을 정상 처리하겠다고 확정하는 명령어로서, 해당 처리 과정을 DB에 영구 저장하겠다는 의미이며, Commit을 수행하면 하나의 트랜잭션 과정이 종료되는 것이다.
Commit을 수행하면 이전 데이터가 완전히 반영되어 UPDATE된다.

Rollback

Roll-back은 작업 중 문제가 발생되어 트랜잭션의 처리 과정에서 발생한 변경사항을 취소하는 명령어이다.
해당 명령을 트랜잭션에게 하달하면, 트랜잭션은 시작되기 이전의 상태로 되돌아간다. 이것은 마지막 Commit을 완료한 시점으로 돌아간다는 말과 상통한다.
즉, Rollback은 Commit하여 저장한 예전 상태를 복구하는 것이다.

MySQL에서 트랜잭션 사용하기

나와 같은 응애 개린이(개발자 + 어린이)들은 주로 MySQL을 다뤄봤을 것이다.

MySQL에서 트랜잭션은 기본적으로 AUTOCOMMIT이 설정되어 있다.
그렇기 때문에, 모든 명령어를 하나하나 수행할 때마다 바로 commit이 된다.

하지만 내가 원하는 논리적인 작업 단위에도 트랜잭션을 걸 수 있다.

START TRANSACTION
    -- 이 블록안의 명령어들은 마치 하나의 명령어 처럼 처리됨
    -- 성공하던지, 다 실패하던지 둘중 하나가 됨.
    -- 부모님 계좌로부터 인출;
    -- 아들래미 계좌로 입금;
COMMIT

이처럼, 내가 원하는 작업의 수행에 따라 트랜잭션을 시작하고 COMMIT 명령어를 통해 작업의 결과를 DB에 반영할 수 있다.

START TRANSACTION을 시작하면, MySQL의 AUTOCOMMIT이 자동으로 off가 된다.
이후, COMMIT이나 ROLLBACK이 수행하게 되면 원래의 AUTOCOMMIT상태로 되돌가 가게 된다.

AUTOCOMMIT

-- 오토커밋 off
SET AUTOCOMMIT = 0;

-- 오토커밋 on
SET AUTOCOMMIT = 1;

-- 오토쿼리 설정 확인
select @@autocommit;

NoSQL에는 트랜잭션을 사용할 수 있을까?

전통적으로 NoSQL은 스케일링과 성능을 중요시하기 때문에 ACID 트랜잭션을 지원하지 않는 경우가 많았다.
하지만, 최근 몇몇 NoSQL에도 트랜잭션 기능을 제한적으로 지원하고 있다.

단 NoSQL에 따라 지원하는 ACID가 다른데, 가장 대표적인 NoSQL인 MongoDB에 대해 알아보자.

MongoDB Transaction

여러 쓰기 작업을 트랜잭션으로 그룹화하고 단일 단위로 완전히 커밋하거나 완전히 롤백할 수 있다.
MongoDB Transaction

추가

MySQL에서 트랜잭션 기능은 MySQL의 엔진에 영향을 받는다.
DB 엔진을 InnoDB로 해야 트랜잭션을 사용할 수 있다.
트랜잭션의 격리 수준과 Lock, 엔진에 대해서는 다음 포스트에 다뤄보겠다.

profile
한 걸음씩 꾸준히

0개의 댓글

관련 채용 정보