1. 트랜잭션(Transaction)이란?
트랜잭션이란 데이터베이스의 상태를 변화시키기 위한 작업 수행의 논리적 단위를 의미한다.
풀어서 설명하자면, 데이터베이스의 상태를 변화시킨다는 것은 우리가 SQL문에 흔히 쓰는 CRUD(SELECT, INSERT, DELETE, UPDATE) 기능을 하는 질의어(Query) 문장들을 일컫는다. 트랜잭션은 하나의 작업을 처리하기 위해 사용자가 임의로 정해둔 필요한 질의어(Query)들의 집합이라고 생각하면 편하다.
예를 들어 내가 누군가에게 10000원을 송금한다고 하였을 때, 그 과정에서 오류가 발생하여 송금은 이뤄지지 않고 내 계좌에서 10000원만 빠져나간다면 서비스의 큰 오점이 될 것이다. 이와 같은 상황을 막기 위해 거래가 성공적으로 끝나야만 완전한 거래로 인식해 승인하고, 오류가 발생하면 아예 없었던 일처럼 원래대로 되돌려 놓아야 한다.
이런 방식으로 시스템의 안정성을 보장하기 위해 개발하는 사람이 지정한 작업 수행의 단위가 트랜잭션인 것이다. DBMS의 성능은 초당 트랜잭션의 실행 수(TPS, Transaction per second)로 측정한다.
2. 트랜잭션의 특징(ACID)
쪼개어지지 않는 원자(Atom, 원래는 쿼크 단위로도 쪼개어질 수 있지만 쪼개어질 수 없는 단위라는 의미에 있어 그렇게 쓰임)와 같이 트랜잭션을 구성하는 연산들이 모두 정상적으로 실행되거나 실행되지 못하면 트랜잭션 자체가 무효여야 한다는 의미이다. 즉, 트랜잭션 안의 연산들은 개별로 실행되어선 안되고, 하나의 단위처럼 모두 실행되거나 실행되지 않아야 한다.
트랜잭션이 성공적으로 수행된 후에도 데이터베이스는 일관된 상태로 유지되어야 한다.
트랜잭션 전 후의 데이터베이스의 상태는 Correct State여야 한다고 하는데, Correct State는 도메인의 유효 범위, 무결성 제약 조건 등의 조건을 위배하지 않는 정상적인 상태를 의미한다.
각각의 트랜잭션은 서로 간섭 없이 독립적으로 수행되어야 한다. 시스템에서 여러 트랜잭션이 동시에 수행되지만, 각 트랜잭션이 독립적으로 수행될 수 있도록 다른 트랜잭션의 중간 연산 결과에 서로 접근하지 못하게 해야 한다.
하지만 격리성을 완전히 보장하려면 각각의 트랜잭션을 순서대로 처리해야 하고, 이는 동시성 처리 성능을 저해시킨다. 따라서 격리성의 수준을 여러 단계(Read-Uncommited, Read-Commited, Repeatable-Read, Serialable)로 나눠 놓았다.
트랜잭션이 성공적으로 완료된 후에는 데이터베이스에 반영한 수행 결과가 어떤 경웨도 손상되지 않고 영구적이어야 한다. 중간에 시스템 문제가 발생했을 때 데이터베이스 로그를 참고해서 성공했던 트랜잭션을 복구 할 수 있다.
3. 트랜잭션의 연산
트랜잭션이 진행되면서 질의문(Query)을 날릴 때마다 DB에 반영이 되진 않는다. 트랜잭션 연산이 성공적으로 완료되는 시점에 실질적으로 DB에 반영이 된다. 트랜잭션 연산에는 크게 두 가지가 있다.
하나의 트랜잭션이 성공적으로 수행되었을 경우에 선언되는 연산이다. Commit 연산이 수행되면 수행했던 트랜잭션이 로그에 저장되고, 최종적으로 DB에 결과가 반영된다.
트랜잭션이 수행되는 중간에 실패하였을 경우에 선언되는 연산이다. Rollback 연산이 수행되면 수행했던 작업들이 취소되고, 트랜잭션 수행 전의 상태로 되돌아간다.(원자성)
원칙적으로는 원자성을 지켜야 하므로 아예 처음부터 다시 시작하여야 하지만, 특수한 경우에는 SAVEPOINT를 지정하고 트랜잭션을 부분적으로 취소할 수 있다.
SAVEPOINT
- 트랜잭션 내부에서 사용자가 지정할 수 있는 세부 작업 단위. 원칙대로라면 원자성을 보장해야 하지만, 매우 긴 트랜잭션의 경우 대부분의 로직이 수행됐는데 마지막에만 문제가 생겨 Rollback이 되면 문제가 발생하지 않은 영역까지 반복해야 하는 불필요한 상황이 발생한다. 따라서 개발자가 임의적으로 트랜잭션을 작게 분할 할 수 있다.(원자가 쿼크 단위로 쪼개지듯)
- SAVEPOINT를 저장했을 경우, ROLLBACK TO SAVEPOINT문을 통해 저장된 곳으로 ROLLBACK 할 수 있다.
- 위의 사진을 보면 COMMIT 명령이 선언된 후, 다음 COMMIT 명령이 선언될 때까지 하나의 트랜잭션이 구성되므로 UPDATE, DELETE, INSERT는 하나의 트랜잭션이 된다. 이 중 SAVEPOINT를 지정하게 되면 하나의 트랜잭션이라고 하더라도 ROLLBACK TO 명령을 통해 SAVEPOINT로 저장한 곳까지로 ROLLBACK 할 수 있다.
4. 트랜잭션의 상태
Active(활성화) : 트랜잭션이 현재 수행 중인 상태.
Partially Committed(부분 완료) : 트랜잭션의 마지막 연산까지 실행했지만, Commit 연산이 실행되기 직전의 상태.
Committed(완료) : Commit 연산을 실행 완료하여 데이터베이스에 최종 결과가 반영된 상태.
Failed(실패) : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태.
Aborted(철회) : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태.
Link
https://mommoo.tistory.com/62,
https://devjem.tistory.com/27#savePoint,
https://memory0136.tistory.com/36,
https://brunch.co.kr/@skeks463/27,
https://devuna.tistory.com/30,