DB 활용에 있어서 빠져서는 안될 주제가 트랜젹선이 아닐까 생각이 듭니다. 그만큼 DB를 활용하는데 있어서
꼭 알고 있어야 하는 필수 개념이 아닐까 합니다.
트랜잭션에 대해 알아보기 이전에 DB를 쓰는 이유는 뭘까요? 사실 데이터를 저장한다면 단순히 파일에 저장해도 되는데,
왜 굳이 데이터베이스에 저장하는 걸까요? 가장 대표적인 이유는 데이터베이스는 트랜잭션이라는 개념을 지원하기 때문입니다!
Transaction
트랜잭션의 사전적 정의는 다음과 같습니다.
데이터베이스 시스템에서 병행 제어 및 회복 작업 시 처리되는 작업의 논리적인 단위로, 사용자가 시스템에 대한 요구 시
시스템이 응답하기 위한 상태변환 과정의 작업 단위이다. 트랜잭션은 커밋되거나 롤백된다.
간단하게 말해서 하나의 작업단위라고 생각하시면 됩니다. 계좌 이체로 예를 들자면 A와 B라는 사람이 거래를 할 때,
A가 B에게 돈을 주면 A의 계좌에서는 돈이 빠져나가고 B의 계좌에서는 돈이 들어와야 합니다. 다시 말해 계좌이체라는
작업은 A에게서 돈을 뺴는 작업 하나와 B에게 돈을 주는 작업 하나로 총 두개로 이루어져있습니다. 이 작업들은 하나의
작업처럼 동작해야 합니다.
만약 A에게 돈을 뻇는데, B에게 돈을 주지 않는다면 서비스에는 심각한 문제가 발생하게 됩니다. 이 때 데이터베이스
에서 제공하는 트랜잭션을 활용한다면, 장애가 발생할 때 해당 작업이 수행되기 이전의 상태로 다시 돌아갈 수 있습니다.
다시 말해 작업 중 하나를 실패해서 거래 이전으로 되돌아가는 것을 롤백(Rollback)이라고 합니다. 만약 모든 작업이 성공
한다면 이를 데이터베이스에 정상적으로 반영해야 되는데 이를 커밋(Commit)이라고 합니다.
이러한 트랜잭션에는 꼭 보장해야 하는 속성들이 있습니다.
Transaction ACID
ACID는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durabilitiy)을 줄인 말입니다. 하나씩 보자면,
원자성은 트랜잭션 내에서 작업들은 하나의 작업처럼 모두 성공하거나 모두 실패해야함을 뜻합니다.
일관성은 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 됨을 뜻합니다.
격리성은 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리해야 됨을 뜻합니다.
지속성은 트랜잭션이 성공적으로 끝나면 그 결과가 항상 기록되어야 함을 뜻합니다.
트랜잭션은 이러한 속성들을 보장하고 있습니다. 이러한 속성들이 보장되는 방법에 대해 알려면 DB세션에 대해 먼저
알아야 합니다.
DB Session
DB 사용자는 서버나 툴을 활용하여 데이터베이스 서버에 접근할 수 있습니다. 이 떄 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게 됩니다. 이러한 커넥션이 생성될 때 DB 내부에는 세션이라는 것을 만듭니다. 커넥션을 통한 모든 요청은 해당 세션을 통하해 실행되게 됩니다. 커넥션의 갯수에 따라 세션의 갯수도 똑같이 만들어집니다.
데이터를 변경하면 바로 DB에 반영되는 것은 아닙니다. DB 명령 마다 자동으로 커밋되게 한다면 바로 반영이 되겠지만
트랜잭션 개념을 활용하려면 오토커밋을 사용하지 않아야 합니다. 다시 말해 데이터 변경 요청을 하더라도 Commit을 하지
않는다면 해당 변경사항은 DB에 반영이 되지 않습니다. 하지만 실제로 DB상에서 보면 데이터가 변경된 것 처럼 보입니다. 실제 예를 들자면,
위 그림을 보면 member 라는 테이블에 이름이 'aaa' 이고 돈이 50000원을 지닌 행을 삽입했습니다.
하지만 commit을 하지 않았기 때문에 db에 정상적으로 반영되진 않습니다.
그런데 밑에 그림 처럼 막상 조회를 해보니 db에 정상적으로 반영된것 처럼 보입니다.
어떻게 된 걸까요? DB에 반영된것 처럼 보이지만, 실제로는 해당 DB세션이 삽입한 행을 임시 상태로 저장하고 있습니다.
다시 말해 다른 DB세션에서 이를 조회한다면, 위와 같이 조회가 되질 않습니다. 해당 세션을 사용한 사용자에게만 보여지
는 것이죠. 이 상태에서 Commit을 하게된다면 다른 db 세션을 사용하는 사람들에게도 삽입된 데이터가 보여지게 됩니다.
만약에 다른 DB세션에서도 커밋하지 않는 데이터들을 볼 수 있게 된다면 이는 데이터 정합성을 훼손하는 것이고 트랜잭션
이 지니는 속성들을 보장할 수 없을 것입니다.
DB세션을 활용하여 트랜잭션의 속성들을 보장하였지만, 예외적인 경우도 존재합니다. 만약에 위의 그림에서
'aaa' 라는 멤버가 지니는 돈을 10000원으로 바꾼다고 가정해봅시다. 어떤 db세션이 해당 데이터를 변경하였고,
아직 커밋은 하지 않았습니다. 그런데 기존의 세션과 또 다른 세션이 'aaa'라는 멤버의 돈을 20000원으로 변경한다면
어떻게 될까요? 이것은 트랜잭션의 원자성이 깨지는 것을 의미합니다. 기존 세션이 commit이 아닌 rollback을 한다면
또 다르세션은 잘못된 데이터를 수정하는 문제가 발생하게 됩니다.
이런점을 방지하려면, 세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에는 commit이나 rollback전까지
다른 세션에서 해당 데이터를 수정할 수 없도록 막아야 합니다. 이떄 등장하는 개념이 db락입니다.
DB Rock
데이터를 수정하려면 해당 세션은 rock을 얻어야 합니다. 만약 해당하는 데이터 행의 rock을 얻었다면, 다른 세션에서는
해당 데이터 행을 변경하지 못합니다. (조회는 가능합니다) 락을 얻은 세션이 수정을 마치고 commit을 하면, 락이 db로
반환되고 db는 요청한 다른 세션에게 rock을 건네줍니다. 다시 말해 rock을 얻은 세션이 수정할 떄 동안, 다른 세션은
데이터를 변경하려면 rock이 반납될때 까지 기다려야합니다.
이상과 같이 트랜잭션은 db에 있어서 가장 중요한 개념이고 DB세션과 DB Rock을 통해서 트랜잭션이 지니는
중요한 속성들이 보장 될 수 있다는 점을 알아봤습니다. 부족한 글 읽어주셔서 감사합니다!
해당 글은 인프런 db접근 기술1을 참고한 내용입니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1/dashboard
'DB' 카테고리의 다른 글
DB 쿼리 성능을 개선해보자 (0) | 2023.04.05 |
---|---|
식별관계와 비식별관계 (0) | 2023.03.28 |
DB Index에 대하여 (0) | 2023.03.10 |
DB 커넥션을 반드시 close 해야하는 이유 (0) | 2022.08.01 |
JDBC에 관하여 (0) | 2022.07.29 |