어떤 은행이 있습니다. 여기서 A라는 사람의 계좌에서 벌어지는 일을 보겠습니다.
오늘은 A의 월급날이라 친구들을 데리고 간만에 한우를 먹으러 가는 날입니다.
A의 계좌에는 500만원이 있고, 아직 월급은 들어오지 않았지만 맛있게 고기를 먹고 있죠.
그리고 계좌이체를 하는 동시에, 회사가 월급을 입금해줍니다.
이러한 과정에서 A의 계좌 잔액은 회사에 의해, 또 A가 결제를 할 때 바뀌게 됩니다.
만약 회사 입장에서 A가 결제를 했다는 것이 갱신되지 않아 잔액이 500만원 그대로라면
월급을 입금했을 때 회사가 바라보는 A의 계좌에는 800만원이 들어있어야 하는데,
실제로는 770만원이 들어있죠? 이러면 데이터의 충돌이 발생합니다.
따라서 변동되는 계좌의 잔액은 고깃집, A 본인, 회사 모두에게 동일하게 공유되어야 합니다.
하나의 예를 더 들자면, 혹시 티켓팅을 해보신 분들이 계신가요?
티켓팅을 할 때 우리를 항상 빡치게 만드는 "이선좌" 역시 트랜잭션이 있기에 가능합니다.
만약 트랜잭션 없이 티켓팅을 한다면,
선택된 좌석이어도 다른 사람 입장에선 빈 좌석이 되므로
한 자리에 두세명씩 중복 예매가 되는 결과가 나오겠죠?
트랜잭션(Transaction)은 데이터의 공유 및 다수의 사용자가 서로 다른 연산을 할 때의 단위 프로세스를 뜻하며,
일련의 과정에서 은행이나 티켓팅 사이트가 수행하는 연산을 바로 트랜잭션이라고 합니다.
다음의 그림은 트랜잭션을 간단히 나타낸 모식도입니다.
4명의 사용자 아래 보이는 색칠된 박스들은 유저가 데이터에 접근중인 시간을 나타낸 것인데요,
이처럼 트랜잭션은 여러 사용자가 한 데이터에 동시에 접근하는 일련의 프로세스입니다.
그런데 2번 유저와 4번 유저가 동시에 한 데이터에 접근할 때 오류가 발생하면 어떻게 될까요?
트랜지션에서 발생하는 오류를 장애(Fail)가 발생했다고 하며,
이를 회복하는 과정에서 Fail이 발생한 트랜지션 자체를 취소하는 걸 UNDO,
log를 이용해서 복구하여 다시 실행하는 것을 REDO 라고 합니다.
트랜지션의 복구에 대해서는 뒤에서 알아보도록 하겠습니다.
트랜잭션의 성질 : ACID
트랜잭션의 성질은 다음과 같으며, 앞글자를 따 ACID라고 부릅니다.
- 원자성(Atomicity)
- 일관성(Consistency)
- 격리성(Isolation)
- 영속성(Durability)
먼저 트랜잭션과 관련된 작업들은 부분이 아닌 전체 연산이 반영되어야 한다는 원자성을 띄고 있습니다.
모든 트랜잭션 연산이 잘 수행되었는데 딱 하나의 연산에 오류가 난다면 트랜잭션 전부가 취소되어야 하죠.
또 트랜잭션은 여러 사용자가 동시에 사용해도 일관성(Consistency)을 보장해야 합니다.
이러한 일관성 보장에는 동시성 제어(Concurrency control)이라는 기능이 필요해요.
또 트랜잭션을 수행할 때 다른 트랜잭션 연산이 끼어들지 못하도록 격리성을 띄어야 하며,
마지막으로 수행 완료된 트랜잭션의 결과는 시스템이 고장나도 영원히 반영되어야 한다는 영속성이 있습니다.
그렇다면 이런 트랜잭션은 DBMS에서 어떻게 수행될까요?
트랜잭션의 수행 : COMMIT, ROLLBACK
하나하나의 트랜잭션은 마치 솔로 플레이 RPG 게임이라고 보시면 됩니다.
이런 게임은 실시간으로 서버에 진행상태가 저장되는 게 아니고, 내가 저장을 눌러야만 저장이 되죠.
트랜잭션도 COMMIT과 ROLLBACK이라는 것이 존재하는데,
COMMIT이 바로 이 저장버튼과 같습니다.
트랜잭션을 수행한 뒤, COMMIT을 해야 해당 트랜잭션의 변화가 저장되죠.
ROLLBACK은 트랜잭션이 시작한 뒤 실행된 모든 동작을 취소(UNDO)하고,
트랜잭션이 시작하기 전 상태로 되돌아갑니다.
한편 게임에서도 자동저장 기능이 있죠? 트랜잭션에서 이 자동저장을 autocommit이라 하며,
일반적으로 MySQL의 경우에는 autocommit이 ON 되어있습니다.
이 ON/OFF 상태를 바꾸려면 다음과 같이 값을 바꿔주면 됩니다.
set autocommit = 0; -- OFF:0, ON:1
성공적으로 트랜잭션이 실행되었다면 COMMIT을 통해 영구적인 갱신으로 영속성(Durability)이 보장되고,
위와 같이 모순이 발생해 트랙잭션의 실행이 실패했다면 ROLLBACK을 하게 됩니다.
이처럼 트랜잭션 과정이 끝나야 commit 및 rollback을 하게 되는 것이 바로 앞서 말한 트랜잭션의 원자성입니다.
트랜잭션의 장애와 회복(Recovery)
앞에서 보았던 모식도를 잠깐 가져와 보겠습니다.
한 사용자가 데이터에 접근하여 Insert, Update 등으로 write를 하려 합니다.
그렇다면 우선 메모리가 디스크에서 데이터를 가져와 CPU가 해당 연산을 수행해 메모리에 excute 합니다.
메모리에서 결과값 데이터가 디스크로 flush 되면 이 결과가 디스크에 적용되는 식이죠.
이제 다음과 같은 트랜잭션 T를 보겠습니다.
초기 값으로 A=900, B=2000이 주어졌다고 하고, 연산 과정을 살펴보면..
아무 이상이 없다면 다음과 같은 연산과정으로 최종 값이 디스크에 저장됩니다.
그런데, 메모리에 저장된 값을 디스크에서 Output 연산을 실행하려는 순간에 전기가 나가면 어떻게 될까요?
Output(B_A)는 정상 수행되고, Output(B_A)연산을 수행할 때 장애가 발생했다고 합시다.
이렇게 되면 메모리에는 B=2100이지만 디스크에서는 B=2000의 값을 가지는 모순 상태가 됩니다.
이런 모순 상태에 돌입하면 회복(recovery)이 필요합니다.
회복의 자세한 과정에 대해서는 다음 글에서 이어서 알아보도록 하겠습니다.
<틀린 점이 있다면 지적 부탁드립니다. 감사합니다.>
'전공 > Database' 카테고리의 다른 글
데이터베이스 : 병행 제어(Concurrency Control) #1 (동시 공용의 문제점, Isolation Level, 직렬 가능성 검사) (0) | 2022.12.12 |
---|---|
데이터베이스 : 트랜잭션(Transaction) #2 (Log, 즉시갱신/지연갱신의 회복, 검사시점, WAL) (0) | 2022.12.12 |
데이터베이스 : INDEX, EXPLAIN (0) | 2022.12.11 |
데이터베이스 : SQL #1 (CREATE) (0) | 2022.10.25 |
데이터베이스 : 관계 모델과 제약 조건 (0) | 2022.10.25 |
최근댓글