1. Transaction이란?
트랜잭션은 데이터베이스의 상태를 변화시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위로 한꺼번에 수행되어야할 일련의 연산을 의미한다.
트랜잭션은 작업의 안전성을 보장해주기에 논리적인 작업을 모두 처리하거나 혹은 처리하지 못 하는 경우에는 원상태로 복구해주는 기능을 제공하며, 사용자의 입장에서는 논리적 단위로 이해할 수 있고 시스템은 데이터를 접근하거나 변경하는 단위가 된다.
트랜잭션의 예시를 들어보자.
A가 B에게 50,000원이라는 금액을 송금하는 Flow를 생각하면, A 통장에서는 50,000원이 빠져나가고, B 통장에서는 50,000원이 추가되어야한다. 하지만 작업 중에 A 통장에서 돈은 빠져나갔지만 B 통장에 50,000원을 추가하는 쿼리에서 에러가 발생하면 데이터의 문제를 야기할 수 있다.
이에 트랜잭션을 사용하면 트랜잭션이 논리적인 작업을 처리를 하지 못 하면 다시 롤백 시켜 데이터의 원자성을 지켜야한다.
2. Transaction의 ACID 특징
트랜잭션은 Atomicity(원자성), Consistency(일관성), Isolation(독립성), Durablility(영속성)의 4가지 특징을 가지고 있다.
(1) Atomicity(원자성)
트랜잭션의 연산은 데이터베이스에 모두 반영되거나 전혀 반영되지 않아야한다. 즉 트랜잭션 내의 모든 명령은 완벽히 수행되어야하며, 모두 완벽히 수행되지 않고 하나의 오류가 발생하면 트랜잭션을 전부 Rollback 해야한다.
(2) Consistency(일관성)
트랜잭션이 그 실행을 성공하면 언제나 일관성 있는 데이터베이스 상태로 변환되어야한다. 시스템이 가지고 있는 고정 요소(PK, FK)는 트랜잭션 수행 전과 트랜잭션 수행 완료 후의 상태가 같아야한다는 것이다
(3) Isolation(독립성)
둘 이상의 트랜잭션이 동시에 병행 실행되는 경우에는 다른 하나의 트랜잭션 실행 중에 다른 트랜잭션의 연산이 끼어들 수도 없으며, 수행 중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조 할 수도 없다.
(3) Durablility(영속성)
성공적으로 완려된 트랜잭션의 결과는 시스템이 고장나도 영구적으로 반영되어야한다.
3. Transaction의 연산 및 상태
트랜잭션에는 Commit, Rollback이라는 2가지 연산과 Active, Failed, Aborted, Partially Committed, Committed의 5가지 상태가 존재한다.
(1) Commit 연산
Commit 연산은 1개의 트랜잭션에 대한 작업이 성공적으로 끝나고 데이터베이스가 다시 일관된 상태일 때, 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산이다. 하나의 트랜잭션이 끝날 때는 반드시 Commit을 해야한다.
(2) Rollback 연산
Rollback 연산은 하나의 트랜잭션이 비정상적으로 종료되어 데이터베이스의 일관성을 훼손할 때, 트랜잭션의 일부가 정상적으로 처리가 되었다고 하더라도, 원자성을 위하여 모든 연산을 취소하는 것으로, Rollback시에는 트랜잭션을 폐기한다.
(3) 상태
- Active(활동) : 트랜잭션이 실행 중인 상태
- Failed : 트랜잭션 실행에 오류가 발생하여 중단된 상태
- Aborted : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태
- Partially Committed : 트랜잭션의 마지막 연산까지 실행했지만, Commit 연산이 실행되기 전 상태
- Committed : 트랜잭션이 성공적으로 종료 되어 Commit 연산 실행 후의 상태
4. 마지막으로
백엔드 엔지니어가 API를 만드는 중에서는 여러개의 데이터의 상태를 한 번에 바꾸는 경우가 존재한다. 위에서 말한 것처럼 A 데이터의 돈을 B 데이터에게 전송을 하는 것은 A 데이터, B 데이터 2개 다 수정해야하는 것이다. 이럴 때 백엔드 엔지니어는 트랜잭션에 대해 신경 써서 원자성을 확보해야한다.