트랜잭션(Transaction)
postgresql을 기준으로 작성되어있습니다.
트랜잭션: 데이터베이스 관리 시스템에서의 최소 상호작용의 단위
개요
데이터베이스 트랜잭션은 데이터베이스에서 수행되는 일련의 작업이며 모두 단일한 논리적 작업 단위입니다. 즉, 특정 트랜잭션을 일부만 수행하거나 결과를 저장하는 경우는 절대 존재할 수 없습니다.
결과는 무조건 성공 / 실패만 존재합니다.
트랜잭션은 여러개의 DML으로 이루어질 수 있습니다.
DML(Data Manipulation Language)이란
데이터 조작 언어라는 뜻으로 CRUD의 행동을 제어합니다.
- SELECT (READ)
- INSERT (CREATE)
- UPDATE (UPDATE)
- DELETE (DELETE)
트랜잭션을 쪼개면 여러 DML이 존재할 수 있습니다.
트랜잭션 예시
가정: 계정 A에서 계정 B로 10달러를 이동
이 작업을 다음과 같이 나눌 수 있습니다.
- 계정 A에서 계정 B로 10달러를 이체하는 레코드(row)를 생성합니다. (트랜잭션의 시작이라고 부름) (CREATE)
- 계정 A의 보유 잔액을 읽습니다. (READ)
- 계정 A의 잔액애서 10달러를 뺍니다. (UPDATE)
- 계정 B에서 잔액을 읽습니다. (READ)
- 계정 B에 10달러를 더합니다. (UPDATE)
위와 같이 진행되며, 시스템 정전 등의 이유로 시스템이 실패하는 경우 트랜잭션을 실행 취소하여 원래 상태로 되돌립니다.
결과는 아래와 같습니다. 성공시에는 커밋을 실패시에는 롤백을 수행합니다.
- 커밋: 변경된 사항을 적용하는 프로세스
- 롤백: 변경된 사항을 적용 전 취소하는 프로세스
데이터베이스 트랜잭션이 필요한 이유는?
데이터베이스 트랜잭션이 왜 존재해야할까요?
- 에러 발생시, DB가 꼬이지 않기하기 위함.
DB 외부에서 일어나는 에러는 어떻게 해결할 수 없습니다. 예를 들면 갑자기 정전이 일어날 수 있습니다.
이런 경우, 보통이라면 보낸 요청의 일부만 적용되어 데이터베이스가 꼬일테지만, 트랜잭션의 결과는 커밋(성공) || 롤백(실패) 밖에 없기 때문에 실패하더라도 문제가 발생하지 않습니다. - *여러 요청이 동시에 데이터베이스 서버에 도달하였을 경우 && 동일한 데이터를 동시에 변경하는 경우, 충돌을 피하기 위함.
*위와 같은 경우, 트랜잭션은 충돌을 피하기 위하여 요청을 서로 격리합니다.
(격리에 대하여는 이후에 따로 설명하겠습니다.)
데이터베이스 트랜잭션 작동 원리
데이터베이스 트랜잭션의 생명주기(Life Cyle) 동안 여러 상태 변화가 있습니다.
아래는 주로 사용되는 트랜잭션의 상태들입니다.
- 활성화(Activate): 트랜잭션 실행 중 첫 상태입니다. 트랜잭션은 명령(읽기 or 쓰기)이 수행되는 동안 활성화됩니다.
- 부분 커밋(Partially Committed): 이 상태에서는 변경이 실행되었지만 데이터베이스는 아직 디스크에서 변경을 커밋하지 않았습니다. 이상태에서 데이터는 메모리 버퍼에만 저장되며 버퍼는 아직 디스크에 기록되지 않았습니다.
중간에 실패할 수 있습니다. - 커밋(Committed): 이 상태에서는 모든 트랜잭션 업데이터가 데이터베이스에 영구적으로 저장됩니다. 따라서 이 시점 이후에는 롤백할 수 없습니다.
- 실패(Failed): 트랜잭션이 실패하거나 활성 또는 일부만 커밋됨 상태에서 중단된 경우에는 실패 상태가 됩니다.
- 종료(Terminated): 커밋되거나 이후의 중단됨(Aborted) 상태 이후의 마지막 상태입니다. 이는 트랜잭션 생명주기를 끝으로 표시합니다.
ACID 속성이 무엇이고 왜 필요한가요?
RDBMS에서 트랜잭션은 원자성(A), 일관성(C), 격리성(I), 지속성(D)이 있어야합니다. 이러한 속성을 줄여 ACID라고 부르며, ACID 속성을 전부 충족하면 안정적으로 처리되어야만 트랜잭션이라고 부릅니다.
원자성 Atomicity
: 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야한다.
트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.
일관성 Consistency
: 트랜잭션 작업 결과는 항상 일관적이어야한다.
DB의 조건이 있다면, 그 조건을 위배하면 안된다. 예를 들면, 마이너스 계좌를 허락하지 않는다는 조건이 존재할 시 이 조건이 위배될 때 Abort를 던져준다.
트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다. 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.
독립/격리성 Isolation
: 각각의 트랜잭션은 서로 간섭없이 독립적으로 수행되어야한다.
트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.
이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다.
은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다.
공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다.
성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다.
이 부분은 다음 글(트랜잭션 격리 수준)에서 다루겠습니다.
지속성 Durability
: 트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야 한다.
성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.
레퍼런스
'CS' 카테고리의 다른 글
데이터베이스 Lock이란 (0) | 2023.03.15 |
---|---|
트랜잭션 격리 수준 (0) | 2023.03.07 |
우리는 왜 JWT를 사용하는가? / JWT 사용 이유 (0) | 2023.02.20 |
[ 개발바닥 2사로 ] 면접 스터디를 시작하며.. (10) | 2023.02.15 |
Git Flow란, 깃 브랜치 전략 (0) | 2022.09.06 |
글 내용 중 잘못되거나 이해되지 않는 부분은 댓글을 달아주세요! 감사합니다! 문의: puleugo@gmail.com