Post

transaction(1)

들어가기에 앞서

벌써 12월 20일입니다. 12월 초입에는 분명 2023년도 한 달 남았네 하면서 넘어 갔었는데 조금 뒤면 2024년이 되네요 숫자가 나름 예쁩니다. 각 자릿수가 2의 배수인게 마음에 듭니다.. 각설하고, database transaction(TXN)에 대해 알아보도록 하겠습니다.

database transaction

2022년 12월, 저가 콘서트 티켓을 YES 24에서 예매하려고 했었습니다. 근데 사람이 너무 많이 몰려서 제가 예매를 하지 못했던 기억이 나네요.

티켓 구매 과정에 대해 자세하게 보려면 아래 사이트를 참조해주세요. http://ticket.yes24.com/New/UserGuide/Ajax/axGuideInfo.aspx

이 상황을 미시적 관점으로 조금 더 생각을 해봅시다. 저라는 사람은 인터넷을 통해서 YES 24 dbms에 접근을 하려고 했습니다. 즉 하나의 공유 자원에 여러 명의 사람이 접근을 하려고 했다고 할 수 있겠네요. 제가 원하던 좌석은 분명 비어있었는데, 클릭을 하니 이미 예약된 좌석이라고 나왔습니다.

image [입구컷 당했던 기억이 ;;;]

아무튼 실패했던 상황에서, 이제부터 저는 transaction이 잘 됐구나! 라고 생각을 할 수가 있어야 한다는 것이죠. 실패해서 짜증나 죽겠는데 이게 뭔 소린지 아직까진 잘 모르겠습니다.

transaction이 없었다고 가정해보겠습니다. 신나게 예매하다가, 나중에 콘서트홀에 가니, 똑같은 좌석의 사람이 두 명 있게 되는 결과가 나오게 될 것입니다.

아직까진 transaction이 뭔지는 모르겠지만, 하나의 공유 자원에 여러 접근이 이루어졌을때, 뭐 어떻게 어떻게 잘 어쩌고저쩌고 되는 이야기에 대한 무엇인가라고 대충 유추할 수 있습니다.

그렇다면, transaction이 뭘까요?

TXN이란?

일단, transaction의 정의부터 시작해봅시다.
transaction이란 실제 세상 작업에서 이루어지는 하나의 작업의 연산의 순서를 이야기합니다.

이게 뭔데… 라고 생각할 수 있습니다. 티켓 예매를 들어서, 다시 예시를 들어보겠습니다.
티켓을 예매하기 위해선, 클릭 후, 개인 정보 입력, 등등 여러 개의 작업을 거쳐야 합니다. 이러한 일련의 세부 작업의 모임이 transaction이라고 할 수가 있습니다.

근데 개인 정보 입력까진 빠르게 하다, 결제를 느리게 하면 당연히 티켓을 뺏길 수 밖에 없습니다. 이러면, 이때까지 했던 작업에 대한, dbms에 저장된 data들은 반영이 되면 안됩니다.

다시, 현실 세계의 관점에서 봅시다.
티켓 예매는 성공하거나, 실패하거나 두 개 밖에 없습니다.
즉, dbms는 작업을 시행하다, 예기치 못한 error로 작업이 실패되면 시행 전 상태로 ROLLBACK 해야함을 보장할 수 있어야 하는 것이죠. log를 남기거나 어떤 방식으로건 보장을 해줘야 한답니다.

sql query를 살펴봅시다.

1
2
3
select * -- txn1 
from table -- txn2
where id=1 -- txn3 

query에서 하나의 문장은 하나의 transaction이라고 생각할 수 있습니다. 즉, 여러 개의 문장은 여러 개의 transaction이라고 생각하기가 가능합니다.

여러 개의 문장을 묶어서, 하나의 transaction을 만든다면, 현실 세계에서의 작업 과정을 나타낼 수 있습니다. 이러한 현실 세계에서 하나의 작업도 여러 개가 아닌, 하나의 transaction으로 처리가 되어야 합니다.

image

바로 이렇게 말이죠.

transaction의 목표

두 가지가 있습니다.

durability and recovery

dbms는 알 수 없는 문제에 대해서 회복 및 내구성을 유지해야 합니다. 회복은 알겠는데, 내구성은 뭘까요? transaction이 성공적으로 처리되면, 그 데이터는 잘 저장되어야 함을 의미합니다.
[출처 : https://postgresql.kr/docs/9.5/tutorial-transactions.html]

[부가 설명 : db 내부에서 하나의 statement들에 대해 다 기억을 한 후, 실패하면 rollback한다고 합니다.]

transaction은 각 작업마다 log를 남겨서, 문제가 생긴다면 이러한 log 기반으로 recovery해야 합니다. 즉, 문제가 생기지 않는다면 반영을 하고, 문제가 생긴다면 이때까지 작업을 취소하고 아무것도 안한 상태로 rollback 해야 한다는 의미입니다. 그래야 data들의 신뢰성을 유지할 수 있기 때문입니다.

concurrency

동시성이라고 합니다.
transaction 내부 statement들이 순차적으로 실행되는 것이 아닌, 하나에 동시에 묶여서 수행함을 이제 이해했습니다. 이는 하나의 transaction 내부 statement를 parallelizing으로 실행한다는 의미입니다.

이러한 transaction을 동시에 여러 host에서 요청한다면 어떻게 될까요?
적절히 잘 문제없이 처리한 후 반영해줘야 한답니다(commit).
어떤 자원에 대해 여러 개의 요청을 하면 적절히 잘 lock을 하는 방식으로 처리를 하지만, 만약 여러 개의 요청이 각자 관련이 없는 자원에 대한 요청이면 동시다발적으로 처리해줘야 하는 것이죠.

티켓 구매가 그 예시입니다. 내가 A 밴드에 대해 티켓 구매를 하는 요청을 하는 동안(txn 내부 statement를 하나의 txn 처리한 여러 요청), 다른 B 밴드에 대한 티켓 구매는 A와 관련 없이(isolated) 행동해야 한다는 의미입니다.

또한, transaction을 동시적으로 해도 데이터는 일관성을 유지해야합니다.(consistency) 이는 여러개의 transaction을 수행하더라도, 일관성(데이터 타입 등)을 유지해야 함을 의미합니다. 예시로 데이터를 write할 때, 타입에 맞추어서 insert 및 update를 해야 한다는 것이죠.

db 특성상, disk엔 많이 접근을 해서, R/W 작업을 해야 합니다. 한 번에 disk에 접근하는 처리율을 throughput이라고 하는데, consistency 및 concurrency가 잘 지켜진다면 단위 시간당 throughput이 오를테고, 이는 성능 향상을 야기합니다.

sql query로 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
--Client 1: 
start transaction
    UPDATE Employee
    SET Salary = Salary + 1000
commit

--Client 2: 
start transaction
    UPDATE Employee
    SET Salary = Salary * 2
commit

transaction을 하지 않는다면, OS 내부 scheduling 방식에 따라 뭐가 먼저 실행이 될 지 모르지만
transaction 처리를 해서, 안전하게 (내부 scheduling 정책에 따라 뭐가 먼저 선택될 지는 모르겠지만) scheduling 정책에 따라 잘 처리해주겠다는 의미가 되는 것이죠.

마무리하며

transaction은 여러 작업을 하나로 묶음으로, 동시 작업 및 회복을 가능하도록 합니다.
다음 글에선, transaction에 대해 좀 더 자세하게 알아보도록 하겠습니다. 제가 아직 시험이 안 끝나서, 시험 끝나면 댓글 기능을 추가 할 예정입니다. 댓글이 안 열려 있다고, 틀린 부분 있으면 메일을 보내주세요.

This post is licensed under CC BY 4.0 by the author.