안녕하세요. SQLER의 코난 김대우입니다.
이번 강좌에서는, 14-1. 트랜잭션과 잠금처리 - 트랜잭션 이해를 진행 하겠습니다.
SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록
이번에 진행할 강좌는 트랜잭션과 잠금처리 - 트랜잭션 이해입니다.
TL;DR
데이터베이스 트랜잭션을 소개합니다. 원자성, 일관성, 격리성, 영속성 - 트랜잭션의 4가지 요건에 대해 설명하고, 데이터베이스가 트랜잭션으로 어떻게 일관된 상태를 유지하는지 정리합니다.
데이터베이스를 공부하면서 “트랜잭션”이라는 키워드는 여러 형태로 사용됩니다. 지난 백업과 복원 강좌에서 데이터 변경이 기록되는 “트랜잭션 로그”에 대해 살펴보았고, 단위 작업이라는 의미의 “트랜잭션” 역시 여러 번 강좌를 진행하면서 말씀드렸습니다.
시스템은 놀고 있는데, SQL 쿼리가 아주 느리거나 실패함
SQL 쿼리 구문을 실행하는 애플리케이션을 개발할 경우에도 이 트랜잭션은 중요하고 속도에 많은 영향을 주게 됩니다. 특히, 동시 다수 사용자 데이터베이스에서 데이터 조회/수정을 진행할 때 - 예를 들어, INSERT/UPDATE/DELETE 와 같은 구문과 SELECT 구문을 잘 못 수행할 경우, CPU나 리소스는 펑펑 놀고 있는데, 처리 속도는 느려지는 사태가 빈번하게 발생합니다. 잠금에 의한 블로킹 / 데드락 현상입니다.
만약, 이런 상황이 종종 발생한다면, 트랜잭션 처리 루틴을 SQL Server Profiler와 같은 모니터링 도구를 이용해 애플리케이션과 SQL 쿼리에서 점검해 보시는 게 좋습니다.
SQLER 강좌에서 이러한 현상을 실제로 유발해 보고 해결하는 방안에 대해서도 진행하니 도움 되시길 바랍니다.
트랜잭션이란 무엇인가
이 챕터 이름이 트랜잭션과 잠금처리입니다. 트랜잭션은 무엇일까요?
트랜잭션은 SQL Server와 같은 데이터베이스에서 가장 작은, 분리할 수 없는 작업의 단위입니다.
은행 계좌이체로 트랜잭션을 풀어 보면,
김대우의 은행 계좌에 500원이 있고. 손석구 님의 계좌에 300원이 있습니다.
김대우는 500원에서 100원을 온라인으로 손석구 님에게 계좌이체 해야 합니다.
은행에서 온라인으로 계좌를 이체하려면 아래와 같이 진행됩니다.
1. 김대우 계좌에서 100원을 뺌: 김대우 계좌 = 400원 손석구 님 계좌 = 300원 2. 손석구 님 계좌에 100원을 더함: 김대우 계좌 = 400원 손석구 님 계좌 = 400원 |
이렇게 은행에서 계좌 이체를 하려고 했는데, 갑자기 정전이 발생해서 1번 작업만 끝내고 은행의 기간계 시스템이 다운되었습니다. 은행에서 그 당시 온라인으로 계좌 이체를 시킨 사람이 1,000명이었다면, 1,000명에게 발생한 이 문제를 어떻게 해결할 수 있을까요?
위의 내용을 우리가 사용하는 SQL 구문으로 바꿔서 실행하면 이렇게 실행될 겁니다.
UPDATE 계좌 SET 금액 = 금액 - 100 WHERE ID LIKE '김대우' UPDATE 계좌 SET 금액 = 금액 + 100 WHERE ID LIKE '손석구'
앗! 주의하세요. SQL Server에서 위의 작업을 하나의 단위 작업으로 묶으려면 다르게 적어야 합니다. 위와 같이 SQL 쿼리를 작성하면 다음과 같이 변환됩니다.
BEGIN TRAN UPDATE 계좌 SET 금액 = 금액 - 100 WHERE ID LIKE '김대우' COMMIT TRAN BEGIN TRAN UPDATE 계좌 SET 금액 = 금액 + 100 WHERE ID LIKE '손석구' COMMIT TRAN
이렇게 자동으로 변화하게 됩니다. 내부적으로 SQL Server의 엔진이 SQL 쿼리를 위와 같이 변환해 수행하게 됩니다. 그렇다면, 어떻게 SQL 쿼리를 작성해야 계좌 이체 작업을 하나의 단위 작업으로 묶어서 수행할 수 있을까요?
다음과 같이, 명시적으로 BEGIN TRAN과 COMMIT TRAN을 사용하면 됩니다.
BEGIN TRAN UPDATE 계좌 SET 금액 = 금액 - 100 WHERE ID LIKE '김대우' UPDATE 계좌 SET 금액 = 금액 + 100 WHERE ID LIKE '손석구' COMMIT TRAN
이렇게 묶어서 사용하면 두 개의 작업이 하나의 단위로 처리가 됩니다.
그렇다면, 데이터베이스 개론 측면에서 트랜잭션을 살펴보도록 하겠습니다.
트랜잭션 4개의 요건
트랜잭션은 DBMS차원에서 다음 요건들을 만족해야만 합니다.
원자성(atomicity)
트랜잭션은 전부(All) 또는 전무(Nothing) 실행만 있으며 일부 작업만 완료/중단하는 처리는 불가능합니다. 계좌 이체 과정에서 출금 작업은 완료했지만, 입금 작업에서 실패했다면, 이 작업은 모든 작업을 실패 상태로 되돌려야 합니다. 즉, 트랜잭션으로 선언한 모든 작업은 성공 또는 취소되어야만 합니다.
일관성(consistency)
트랜잭션이 그 실행을 성공적으로 완료하면 언제나 일관된 데이터베이스 상태가 유지되어야 합니다. 즉, 트랜잭션 실행으로 데이터베이스의 비즈니스 규칙이나 데이터베이스 무결성이 위배되지 않는 일관된 데이터베이스 상태가 유지되어야 합니다.
격리성(isolation)
여러 트랜잭션이 동시에 실행될 경우, 한 트랜잭션 연산의 중간 결과를 다른 트랜잭션이나 작업이 접근할 수 없도록 격리되어야 합니다. 즉, 한 트랜잭션이 완료하기 전까지 다른 트랜잭션은 해당 트랜잭션의 결과를 참조할 수 없도록 격리됩니다. 이어지는 강좌에서 트랜잭션 격리 수준(Transaction Isolation Level)이 진행됩니다.
영속성(durability)
트랜잭션이 완료되면 트랜잭션 결과를 데이터베이스에 반영하고 어떠한 경우에라도 보장받습니다. 이 요건이 영속성입니다.
약간 어렵게 느껴질 수 있습니다. 앞으로 차근차근 내용을 진행하니 너무 걱정 안 하셔도 됩니다. 그렇다면, 트랜잭션 장애나 시스템 장애 상황에서 어떻게 회복이 될까요? 이때, Checkpoint와 Redo / Undo를 이용하며, 다음 강좌에서 상세히 살펴봅니다.
데이터베이스 장애(Failure)와 회복(Recovery)
데이터베이스 회복(Recovery)이란, 데이터베이스 장애(Failure)가 발생했을 때 데이터 베이스를 장애 이전의 상태로 다시 복원시켜 일관된 상태로(consistent state)로 되돌리는 작업입니다. 이런 장애를 조금 더 세분화를 시켜야 오늘 진행할 트랜잭션 장애와 차별화가 가능합니다.
트랜잭션 장애
트랜잭션 처리 중에 논리적 오류나 내부 조건, 입력 데이터 불량, 데이터 불명, 시스템 자원의 과다한 사용 요구 등으로 정상적인 실행을 계속할 수 없는 상태.
시스템 장애
하드웨어나 플랫폼 오류로 메인 메모리에 있는 정보의 손실이나 교착 상태가 발생해 더 이상 실행을 계속할 수 없는 상태를 의미.
미디어 장애
디스크와 같은 저장 미디어 오류로 저장 장치의 데이터베이스 일부 또는 전부가 손상된 상태를 의미.
이런 다양한 장애 상황에서도 데이터베이스는 트랜잭션을 이용해 일관된 상태를 유지합니다.
그럼 다음 강좌에서 실제 쿼리를 이용해 트랜잭션을 조금 더 살펴보도록 하겠습니다.
SQL 강좌 책 구매
강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다.