[DB] 트랜잭션이란?

J-USER·2023년 1월 15일
0

DB

목록 보기
1/2
post-thumbnail

Intro

현업에서 실무를 진행하며, 필연적으로 DB에 접근하는 무수하고 복잡한 쿼리를 접하게 되었다. 실력있는 백엔드 개발자라면 DB 접근을 얼마나 효율적이고 "잘" 다루는지에 따라 나뉜다고 해도 과언이 아니다. 왜냐하면 DB 접근을 이전보다 10% 빠르고 효율적으로 수정했다면 곧 서버의 운영비용을 절감 시키는 비용 의 절감으로 이어지기 때문이다.

이전의 프로젝트는 소규모 였기 떄문에 트랜잭션에 대한 큰 이해가 없어도 장애없는 DB를 사용할 수 있었지만..(ex REPEATABE READ, SERIALIZABLE..) 점점 이러한 지식의 부족을 인지하고 있었고, 다소 여유가 생긴 지금 트랜잭션에 대해 정리해보려고 한다! 목표는 어딜가서 누가 물어보면 아주 확신을 가지고 말할 수 있도록!!! 아마 몇편에 나눠서 포스팅을 진행할 것 같다!!

트랜잭션이란??

트랜잭션은 DBMS가 DB를 다룰 때 사용하는 논리적인 작업 단위다. 이때 논리적 단위는 하나의 작은 작업의 묶음 덩어리다.

🙋 벌써 어려운데 하차해도 됩니까? 한줄 요약 부탁드려요.
🤖 ALL or NOTHING
🙋 너무 줄이면 어쩌자는 겁니까;;; 그게 뭡니까?

간단한 예시를 들자면, 만약 당신이 친구에게 100만원을 입금 한다고 가정하자. 그런데 어라? 에러가 발생했다. 여기서 친구에게 송금될 금액은?
1. 100만원
2. 일부
3. 0원

🙋 이게 문제야? 0 원이지 에러났으면 입금되면 안되지!!!
🤖 정답.

그렇다면 반대로 만약 입금했을 때, 성공적으로 입금이 완료 되었다. 이때 입금된 금액은?
1. 100만원
2. 일부
3. 0원

🙋 장난? 당연히 다 입금 돼야지!
🤖 정답.

은행에 입금하는 것은 다양한 로직을 거쳐 DB에 접근하는 것을 의미한다. 그렇기 때문에 정말 단 하나라도 이상이 생기면 모든 작업이 수행되지 않는다. 그래서 트랜잭션은 모두 실행되거나 모두 실행하지 않거나. ALL or NOTHING을 기억하자.

🙋 근데 ALL or NOTHING 처리를 어케 하는데?
🤖 완료시 Commit, 실패시 Rallback
🙋 그럼 그건 어떻게 작동하는데?
🤖 좀 이따 알려줌 ㅎ

트랜잭션은 크게 4가지 일을 하는데 CREATE , UPDATE , DELETE , SELECT 이다. 이중에 SELECT 는 조금 특별한데, 읽고 있는 데이터가 중간에 수정될 수 있기 때문이다. 그래서 이를 방지하기 위해 트랙잰션의 isolation level 을 설정해 사용하는 것을 잊지말자!

🙋 아니 근데 그냥 순차적으로 해버리면 중간에 수정되는 걸 방지할 수 있자너?
🤖 병렬 처리를 하지 않으면 데이터 부정합을 해결할 수 있지만 요청이 많아지면 처리가 어렵기때문에 쩔 수 없음.

트랜잭션의 생명주기

위에서 말한것 처럼 완료시 Commit이 실패시 Rollback이 진행된다. 그럼 자연스럽게

🙋 그래서 아직 실패인지, 성공인지 모르는 상태의 트랜잭션은 어케 처리하는데?

라는 질문이 나올 수 있다. 그래서 트랜잭션의 생명주기를 나열하자면,
1. Active States : 트랜잭션이 실행되고 있는 상태
2. Partially Committed: 트랜잭션이 실행되면서 데이터 변경사항을 DB에 적용 전 메모리 공간에만 변경해놓은 상태

3-1. Commited : 실제로 메모리에서 DB에 데이터를 쓴 상태. (Rollback 불가)
3-2. Failed : 에러로 트랜잭션이 취소된 상태

  1. Terminated State : 트랜잭션이 성공해 영구 반영되거나 실패해서 롤백된 후 실질적으로 트랜잭션의 종료인 상태.

트랜잭션의 특성 : ACID

전공자면 전공 수업에서도, 정보처리기사 시험에서도 주구장창 나오는 말이었지만 정작 자세히 알진 못했다. ACID는 트랜잭션하면 꼭 알아야할 특성이다. 이상적으로는 모든 트랜잭션은 이 특성을 만족해야하지만... 현실적으로 완벽히 지켜지기란 아주 쉽지않다.. 왜냐면 모두 엄격히 지켜버리면 DB의 성능을 포기해야하기 때문이다. 자세히는 왜인지 하나씩 뜯어보며 알아보자!

Atomicty (원자성)

원자성은 앞에서 말했던 ALL or NOTHING 을 의미한다. 트랜잭션 내의 모든 작업이 모두 반영되거나, 전혀 반영되지 않아야한다는 것이다. 즉, 커밋 이전에는 디스크에 쓰지 않고 메모리 버퍼에만 저장해 두었다가 중간에 실패하면 디스크에 반영하지 않는 방식으로 원자성을 보장한다.

Consistency (일관성)

일관성은 모든 트랜잭션이 정해진 규칙을 어기지 않고 오류가 없는 일관적인 상태임을 의미한다. 예를 들어 한도가 100만원인데, 트랜잭션 중 100만원 이상의 금액을 송금하는 작업은 할 수 없다던지, 문자열이 들어온다던지 등..당연히 지켜야할 규칙을 일관적으로 지킴을 의미한다. (다소 당연한 것...)

Isolation (격리성)

격리성은 하나의 트랜잭션을 수행할 때 다른 트랜잭션이 접근할 수 없음을 의미한다. 즉 모든 트랜잭션은 다른 트랜잭션으로부터 독립되어야 한다.

🙋 아니 그럼 동시 처리 못하는거랑 다름이 없잖아?? 다른 사람 하는거 기다려야해???
🤖 ㄴㄴ 1,2,3,4 모두 같이 요청해도 마치 1 -> 2 -> 3 -> 4 처럼 수행하듯이 만들어야 한다는것. 이게 Serializability 다.
🤖 이건 내용이 많아 나중에 따로 다룰게

Durability (지속성)

지속성도 너무 당연한 이야기다. 커밋 되었다면 영원히 지속 되어야한다는 특성이다.

🙋 아니 너무 당연한걸 왜 넣었는데?
🤖 영원히 지속 = 성공 로그를 남김 = 문제 생기면 복구 가능

단순하지만 꼭 필요한 특성이다. DBMS가 이 지속성을 위해서 종류마다 다르게 동작하고 격리성도 마찬가지로 조금씩 다르다. 그래서 모든 DBMS가 같지않고 어떤 DBMS를 사용하는지에 따라 맞춰 공부할 필요가 있다.

profile
호기심많은 개발자

0개의 댓글