데이터베이스 트랜잭션의 사용처와 특징

 

데이터베이스의 강력한 기능중 하나인 트랜잭션을 이해하고 어느때 사용하면 좋을지, 장점은 뭐고 단점은 어떤것이 있는지 살펴보고, 트랜잭션이 가지는 특징에 대해서 알아보도록 하자

 

 

 

트랜잭션이란?


 

 

우선 먼저 트랜잭션의 뜻을 알아보면 ' 하나의 논리적 기능을 수행하기 위한 작업의 단위 ' 라고 설명할수있다

해당 뜻은 우리가 서비스를 진행함에 따라 여러개의 쿼리문이 엮이는 상황을 흔히 볼수있을것이다

당장 예를들어봐도 조회수 100 이상의 게시물을 인기 게시물 테이블로 옮기고싶을때 이런작업을 거칠수있다

 

게시물 테이블에 조회수 100이상의 게시물을 SELECT 한다 (1)

SELECT 한 게시물테이블을 인기 게시물 테이블로 옮기는 INSERT 작업을 한다 (2)

게시물 테이블에 조회수 100이상의 게시물의 삭제상태를 1로 UPDATE 한다 (3)

 

이러한 로직이 있을때 우리는 총 3번의 쿼리가 발생한다는 것을 확인할수있다 SELECT, INSERT, UPDATE

물론 위에 예시는 이해를 돕기위해 아주 단순하게 간략화 하여 로직을 구상해보았는데 여기서만약에 (2) INSERT하는 작업이 서비스 장애로인해 수행이 안되었다고 가정을 해본다

 

그러면 총 3번의 쿼리에서 2번째가 빠지게되며 ' 인기 게시물 테이블로 옮기는 INSERT 작업 ' 이 제대로 수행되지 않았다는 것을 알수있다

그러면 인기게시물 테이블로 조회수 100이상의 게시물이 INSERT되는 작업이 안되고 애꿎은 게시물테이블에 조회수 100이상의 게시물이 삭제된것을 확인할수있다

만약 이러한 과정이 결제시스템과 같이 현실세계의 돈이 직접 오고가고 하는 로직안에서 일어났다고 생각해보면 정말... 큰문제로 이어질수있다

 

그걸 방지하기 위해서 우리는 여러개의 쿼리가 하나의 로직안에 동작할경우 하나로 묶어서 단위로 만드는것을 트랜잭션이라고 한다 

이렇게되면 트랜잭션의 기능을 통해서 위에서 언급한 오류를 대처할수있게된다 이것에 대해서는 계속 자세히 알아보도록 하자

 

 

 

 

 

 

트랜잭션의 특징


 

트랜잭션의 특징이라 하면 흔히 ACID를 생각할수있다 ACID는 각각 원자성, 일관성, 격리성, 지속성 이라는 뜻을 가지고있으며 하나한씩 어떤 의미를 내포하고있는지 살펴보도록 하자

 

 

 

첫번째로 원자성(Atomicity)는 트랜잭션이 적용된 로직들은 모두 수행이 되었거나 수행이 되지않았음을 보장하는 의미이다

이게 무슨말이냐면 위에서 예시로 들었던 3개의 쿼리문을 생각해보면 모두 정상적으로 처리되었을경우에는 문제가 전혀없다

하지만 문제는 중간에 하나의 쿼리만 서비스장애로인해 정상적으로 수행되지 않은것을 가정했었는데

이러면 3개의 쿼리문 전체가 롤백이 되어버린다

 

다시 정리해보면 3개의 쿼리문이 모두 수행이 됬을경우 Commit하여 정상적으로 데이터베이스에 갱신이 되지만 만약 하나라도 누락되었을경우 Rollback을 통해 없던일로 처리하여 아무일도 일어나지 않는다

이러한 기능덕분에 결제시스템 중간에 오류가 났을경우 오류메세지를 사용자에게 띄워주고 다시 처음부터 결제를 진행할수 있도록 도와준다

 

이것이 트랜잭션의 첫번째 특징인 원자성이라고 볼수있다

 

 

그다음 두번쨰 일관성(Consistency)에 대해서 알아보도록 하자

우리가 만약 아는사람에게 100만원을 계좌이체 해줄려고하는데 잔고에는 50만원밖에 남아있지 않는다

이럴경우에는 송금이 되지않아야하는데 이렇게 허용된 방식으로 즉 데이터베이스의 기록된 모든데이터들은 서비스에맞는 조건 및 규칙에 따라서 유효성을 가져야 한다는것이다

 

사용자의 잔고에 -50만원 이런식으로 붙게되면 이는 일관성이 보장되지않는다

트랜재겻닝 실행되기 전과 후 모두 데이터베이스이 일관성이 유지되어야 데이터의 불일치가 일어나지 않을수있다

 

 

다음 세번째는 독립성(Isolation)이로써 동시에 실행되는 트랜잭션들은 서로 영향을 미치지않도록 격리되어 있어야한다

독립성 같은경우에는 되게쫌 헷갈린데 차근차근 알아보도록 하자

 

 

 

 

독립성(Isolation)


 

우리가 서비스를 진행함에 따라서 사용자는 항상 한명이 아니다 여러명의 사용자들이 동시에 요청하는경우가 빈번할것이다

이럴경우 만약 토랜잭션이 2개가 동시에 일어난다고 가정했을때 1번째 트랜잭션이 진행하던 도중에 중간에 오류가나서 롤백이된다면 2번째 트랜잭션에 영향을 줄수가있다

이것은 데이터베이스 개론 3판에 좀더 자세히 설명되어있는데

 

 

 

위에 사진처럼 1번째 트랜잭션은 X = 3000의 값을 읽어 X에 1000원을 더하는 작업을하고 데이터베이스에 X의 값을 새로갱신한다 그러면 데이터베이스 X에는 4000원이 있을텐데 여기서 두번째 트랜잭션이 들어오게되어 현재 X의값인 4000원을 읽어오고 해당 4000원의 0.5를 곱해 2000원으로 만든다 그다음 Y = 3000을 읽어오고 똑같은 작업을하여 1500원을 다시쓴다

 

여기서 문제가 발생하는데 처음 첫번째 트랜잭션이 수행되었을떄는 X에는 3000원 Y에는 3000원이 있었지만 중간에 2번째 트랜잭션이 수행하여 Y의값을 1500원으로 만들어버린다

 

이러면 첫번째 트랜잭션을 본래 Y = 3000으로 읽어와야하지만 두번째 트랜잭션으로 인해 Y = 1500을 읽어오게된다

만약 여기서 중간에 오류가생겨 롤백이된다면 더 어지러워 진다

 

이처럼 동시에 실행되는 트랜잭션은 서로영향에 미치지않게 격리되어야 데이터의 일관성을 지킬수있으며 이는 순차적으로 진행되는것이 가장 바람직하나 성능문제로인해 격리수준을 조절하는것이 가능하다

 

격리수준에 대해서는 따로 포스팅하여 정리해보도록 하겠다

 

 

 

마지막 4번째는 지속성(Durability) 로써 트랜잭션이 성공적으로 수행되게 되면 그에따른 결과는 영원히 반영되어야한다는 것을 의미하는데 이는 서비스장애나 예외발생시 트랜잭션의 결과는 보존되어있어야 한다는 뜻을 가진다

 

이를위해 데이터베이스는 만약 롤백이 일어났을경우 저널링을 통해 변경사항을 로깅하는 것을 지원하며 체크섬을 통해 데이터의 무결성을 보호하는 등 여러 기능들을 지원해준다

 

 

 

트랜잭션의 장단점


그래서 결국 트랜잭션으로 인해 얻을수있는 장단점은 무엇일까?

사실 위에서 언급한 모든것들이 장점이다 원자성을 통해 중간에 서비스장애 발생시 수행쿼리를 롤백시켜 안전하게 시스템을 지켜주고 일관성을 통해 올바른 데이터를 가지게 도와주는등 여러 보안적인 측면에서 강력한 기능이 된다

 

하지만 이런 강력한 기능덕분에 전반적인 시스템성능을 저하시킬수있는데 가장 예로들면 트랜잭션 실행중에는 데이터베이스의 특정부분이 Lock이 될수있는데 이는 다른 트랜잭션의 대기시잔을 증가시킬수있으며, 트랜잭션중 오류가 발생하거나 시스템이 고장나게되면 결국 회복 및 복구작업이 필요하다

경우에 따라 복잡하며, 시간이 오래걸릴수있고 기본적으로 트랜잭션은 많은 시스템자원을 요구한다

 

메모리, 디스크, 대역폭 등 많은 트랜잭션이 동시에 실행될때 시스템자원의 한계를 초과할수있으며, 이로인해 성능저하가 발생될수도있다

 

만약 대규모 트래픽이 발생하고, 트랜잭션을 어느정도 타협을 본다면 NoSQL도 고려해보는것이 좋으며, Redis를 Cache 저장소로 두어 좀더 유연한 서비스 설계를 가능하도록 만드는것이좋다

 

만약 NoSQL과 RDB의 장단점을 알고싶다면 여기를 클릭해보도록 하자

 

 

 

여기까지 데이터베이스의 트랜잭션과 장단점, 사용처, 특징에 대해서 알아보았다