본문 바로가기
My Image
전공지식/DataBase

[DataBase] 트랜잭션이란? (Transaction)

by Lim-Ky 2017. 10. 6.
반응형

트랜잭션(Transaction) 개념


C나 Java와 같은 프로그래밍 언어로 작성된 응용 프로그램은 명령어들의 집합으로 볼 수 있는데, 이러한 프로그램들은 세부적으로 여러 개의 함수나 클래스 단위로 구성됩니다. 함수나 클래스들은 전적으로 프로그래머가 프로그래밍의 편리성과 효율성 중심으로 설계한 결과물입니다. 

그러나 데이터베이스 응용프로그램에서는 프로그램의 구성을 다른 관점으로 살펴 볼 수 있습니다. 예를 들어 은행 업무에 관련된 데이터베이스 응용 프로그램을 가정해봅시다. 이 프로그램은 계좌이체, 대출, 예금, 출금 등과 같이 은행에서 이루어지는 여러 가지 업무처리에 관련된 세부 프로그램들로 구성됩니다. 이러한 세부 프로그램들은 사용자 입장에서 보면 하나의 작업 단위가 됩니다. 그리고 이러한 작업들을 수행하기 위해서는 세부적으로 여러가지의 데이터베이스에 대한 연산(검색, 삽입, 삭제, 수정)들을 필요로 합니다. 



예를 들어 A계좌에서 B계좌로 일정 금액을 이체한다고 가정해봅시다. 이를 위해서는 그림과 같이 A계좌의 잔액을 확인하고 현재 금액에서 인출할 금액을 뺀 나머지 금액을 다시 저장합니다. 그런 다음 B계좌의 잔액을 읽어 들인 후 이체된 금액을 더하고 그 합을 다시 저장하면 계좌이체가 완료됩니다. 이러한 과정들이 모두 합쳐져 계좌이체라는 하나의 작업단위를 구성합니다. 데이터베이스에서는 이와 같은 하나의 논리적인 작업 단위를 구성하는 연산들의 집합을 트랜잭션이라 합니다. 이러한 관점에서 데이터베이스 응용 프로그램은 트랜잭션들의 집합으로 정의 할 수 있습니다.





트랜잭션(Transaction) 필요성


트랜잭션을 정의하는 이유는 무엇일까요? 그 동안 알지 못했지만, 우리는 현실에서 트랜잭션을 간접적으로 경험하고 있습니다. 계좌이체를 다시 생각해봅시다. 많은 사람들이 현금 인출기에서 카드를 이용하여 계좌이체를 한 경험이 있을 것입니다. 이때 현금 인출기를 작동하는 도중에 기계오류나 정전 등과 같은 예기치 않은 상황이 발생하여 카드가 나오지 않거나 기계가 멈추는 경우가 있습니다. 이때 가장 우려되는 것이 내 계좌에서는 금액이 빠져나간 것으로 기록되고 정작 상대방 계좌에는 이체가 되지 않는 상황입니다. 트랜잭션이란 바로 이러한 문제가 발생되지 않도록 하는 강력한 수단을 제공해주는 것입니다. 즉, 내 계좌에서 금액이 빠져나가기 전 상태로 돌아가던지, 아니면 상대방 계좌로 이쳬가 성공적으로 끝나도록 보장해줘야 합니다. 


계좌이체 과정에서 발생 할 수 있는 문제점을 좀 더 구체적으로 알아보기 위해 그림을 다시 봅시다. 이 그림에서 A계좌에서 이체할 금액을 인출한 다음 B계좌에 이체된 금액을 저장하기 전에 어떠한 이유로 해서 실행이 중단되었다고 가정해봅시다. 즉, 그림에서 마지막 명령문 WRITE t 가 실행되지 않은 상황을 의미합니다. 그러면 A계좌에는 이미 잔액이 인출된 결과가 저장되었지만, B계좌는 변경이 되지 않은 채로 남아있게 됩니다. 은행 업무에서 이러한 결과는 결코 발생되면 안됩니다. 즉, 계좌이체를 실행 할 때는 계좌이체에 정의된 모든 연산을 완벽하게 실행하던지, 아니면 모두 실행하지 않고 처음의 상태로 남아있어야 합니다.


또 다른 예로 은행에서 현금을 인출하는 과정을 살펴보면, 은행에서 예금을 인출하는 작업은 다음과 같은 연산으로 이루어집니다.


1. 예금 잔액을 확인한다.

2. 해당 인출금을 잔액에서 뺀다.

3. 인출금을 뺀 나머지를 새로운 잔액으로 저장한다.

4. 인출금을 지급한다.





만약 현재 잔액이 500원인 계좌에 대해 두 사람이 각각 A지점과 B지점에서 동시에 100원을 인출하는 작업을 진행한다고 가정해 봅시다. 이 상황은 위 그림과 같습니다. 이 그림을 보면 우선 A와 B에서 예금 잔액을 읽고 동시에 그 값이 500원이라는 것을 확인 합니다. 다음 두 지점에서 각각 잔액 500원에서 100원을 뺍니다. 그러면 A와 B모두 잔액이 400으로 계산되어, 400원을 각각 저장합니다. 마지막으로 100원을 A와 b 모두에서 지급합니다. 결국 A와 B지점에서 각각 100원씩 인출하여, 결국 200원을 인출한 셈이 되고 잔액은 400원이 됩니다. 이 상황도 올바르지 못합니다. 이러한 오류의 원인은 A지점에서 잔액으로 400을 저장하였고, B지점에서도 400원을 저장함으로써, 둘 중 하나가 다른 지점에서 저장한 잔액을 덮어 써버렸기 때문입니다. 결국 다중 사용자 환경에서 하나의 트랜잭션이 동시에 실행되는 다른 트랜잭션에 의해 영향을 받은 결과입니다.


따라서 지금까지 예를 든 상황과 같이 원하지 않는 결과가 발생되지 않도록 사전에 방지하기 위해서 트랜잭션은 필요합니다. 현재 대부분의 DBMS들은 이러한 상황을 방지하기 위한 기능을 갖추고 있습니다. 이를 위해 데이터베이스 개발자는 작업 단위들을 트랜잭션으로 적절히 정의해야 합니다. 즉, 트랜잭션을 정의하는 것은 전적으로 개발자의 의무이지만, 정의된 트랜잭션들에 대해서 위와 같은 문제가 발생하지 못하게 방지하는 것은 DBMS의 몫입니다. 





트랜잭션(Transaction)의 특징(지켜야 할 조건)


지금까지 설명한 내용을 토대로 트랜잭션의 특징을 정리해보겠습니다. 중요한 개념이기 때문에 꼭 암기해서 외워야합니다. DBMS는 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 지속성(Durability) 이 만족해야 합니다. 

다음 조건들의 영어 첫 단어를 인용해 ACID 특성(ACID property)라고 합니다. 



  원자성(Atomicity)

트랜잭션 실행 도중에 문제가 발생했을 경우, 중단된 상태가 아닌 모두 실패하거나, 모두 완성 둘 중 하나의 상태가 되어야 합니다. 즉 100개 명령어로 구성된 트랜잭션 중 99개 완료 1개 실패가 된다면, 이는 무조건 실패로 간주하여 트랜잭션 시작 전 상태로 돌려야 합니다. 또한, 100개 모두가 성공했을 시 트랜잭션은 성공합니다. 따라서 중간상태란 없습니다.  

 일관성(Consistency)

일관성이란 트랜잭션 완료 후에도 데이터베이스가 일관된 상태로 유지되어야 합니다. 예를 들어 계좌이체를 성공적으로 실행했다면, A계좌의 잔액과 B계좌의 잔액의 합이 트랜잭션 실행 전의 합과 동일해야 합니다.  

 고립성(Isolation)

고립성이란 하나의 트랜잭션이 실행하는 도중에 변경한 데이터는 이 트랜잭션이 완료될 때까지 다른 트랜잭션이 참조하지 못하게 하는 특성입니다. 하나의 트랜잭션이 A라는 계좌에서 작업을 하고 있다면, 다른 트랜잭션이 A계좌에 대해 참조하거나 관여 할 수 없고 작업이 끝날 때까지 대기하거나 해야합니다. 

 지속성(Durability

지속성은 트랜잭션이 완료되면, 주기억장치가 아닌 디스크와 같은 보조기억장치에 저장되거나 그렇지 않더라도 시스템 장애가 회복되고 난 후에 어떠한 형태로든지 그 데이터를 복구 할 수 있게 해야함을 뜻합니다.  






트랜잭션(Transaction)의 상태



이제 앞서 설명했던 트랜잭션이 갖추어야 할 조건들 ACID 특성을 충족시키기 위해선 트랜잭션이 현재 어떤 상태인지 정의할 필요가 있습니다. 이에 따라 트랜잭션 각 상태에 따라 어떤 상황인지 알아봅시다. 




Active(활동)

트랜잭션이 실행 중에 있는 상태, 연산들이 정상적으로 실행 중인 상태

Failed(장애)

트랜잭션이 실행에 오류가 발생하여 중단된 상태 

Aborted(철회) 

트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태 

Partially Committed(부분 완료)

트랜잭션이 마지막 연산까지 실행했지만, Commit 연산이 실행되기 직전의 상태 

Committed(완료) 

트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태 



트랜잭션에 대해서 이번시간에 알아보았는데요.. 데이터베이스에서 참 중요한 개념 같습니다.

다음 시간에는 데이터베이스 동시제어, 데이터베이스 회복에 관해 알아보겠습니다. 




반응형

댓글