사용자의 요청을 해석하여 데이터베이스에 저장된 정보를 관리할 수 있게 도와주는 소프트웨어
ex) MySQL, Oracle DB, Maraia DB 등
=> "하나의 논리적 작업 단위를 구성하는 일련의 연산들의 집합"
=> 즉, 이 트랜잭션을 사용하면 DB의 상태를 변화시킨다는 것이다. (질의어로 DB에 접근하는 것)
예를 들어
1. A계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.
2. B계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.
3. A 계좌에서 10000원을 인출한 값을 저장한다.
4. B 계좌에서 10000원을 입금한 값을 저장한다.
5. A 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.
6. B 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.
[간단한 용어 정리]
Commit
:이와 같은 상황을 예시로 들었을 때 트랜잭션에는 2가지 방법을 가지고 있다.
이 2가지의 기준은 Commit이 들어가는 위치에 따라 나뉘는데 일반적으로는 사용자에게 빠른 응답을 위해 4번까지 수행 후 -> commit -> 5,6 의 방법 1을 많이 쓴다고 한다.
- 방법 2 : 6번까지 종료한 후 Commit
1) BEGIN
the transaction
2) EXECUTE
several queries
(아직 DB 내에 갱신이 적용되지 않는다)
3) COMMIT
the transaction
(트랜잭션 성공, 갱신이 실제 적용됨)
만일 이 2번째 단계에서 쿼리들 중 하나라도 실패하게 된다면?
=> DBMS는 전체 트랜잭션 or 실패한 쿼리를ROLLBACK
한다. (DBMS 설정에 다르긴 함)
Atomicity(원자성), Consistency(일관성), Isolation(독립성), Durability(영구성) 으로 구성되어 있다.
All or nothing
특성만약 이체 과정 중 트랜잭션이 실패하면, 옮기던 돈이 사라지는 일이 발생하면 안되므로 완료되지 않은 트랜잭션의 중간상태를 DB에 반영해서는 ❌
- 무슨말인가?🤔
A라는 상태의 계좌가 트랜잭션을 진행하는 중에 특정요인으로 DB가 변경되어 A->B 상태가 되어도
B상태의 DB에서 트랜잭션이 진행되는 것이 아닌 초기의 A상태의 DB로 진행된다는 것을 의미한다.
- 무슨말인가?🤔
이 성질을 보장받지 못하면, 특정 트랜잭션이 잘못되어도 원래 상태로 ROLLBACK을 할 수 ❌
COMMIT
연산은 실행 XCOMMIT 연산
을 실행한 후의 상태ROLLBACK
연산을 수행한 상태commit요청이 들어오면 상태는 부분완료 상태가 된다. 이후 commit을 문제없이 수행 할 수 있다면 완료 상태로 전이되고, 만약 오류가 발생하면 실패 상태가 된다.
=> 즉, '부분완료'는 commit 요청이 들어왔을 때를 말하며, '완료 상태'는 commit 을 정상적으로 완료한 상태를 말한다.
일반적으로 데이터베이스 커넥션은 개수가 제한적 이므로 이를 소유하는 시간이 길어진다면 사용할 수 있는 커넥션은 점점 줄어들기에 이를 기다리는 시간이 발생할 수 있다!
그러므로 트랜잭션은 필요한 최소의 코드에만 적용하자 👍
트랜잭션들끼리 일관성 있는 데이터를 얼마나 허용할 것인지 정해놓은 수준
=> 즉, 트랜잭션 수행 중 다른 트랜잭션이 해당 데이터를 조회하는 것이 가능한 정도를 결정해 놓은 것
COMMIT
이나 ROLLBACK
여부에 상관없이 다른 트랜잭션에서 값을 읽을 수 있다.😥문제점:
Dirty Read, Non Repeatable Read, Phantom Read 문제가 모두 발생할 수 있다.
트랜잭션 1이 COMMIT 하기 전에 트랜잭션 2의 SELECT 결과는 '제니'였다.
하지만 트랜잭션이 1이 COMMIT 하고 난 후의 SELECT 결과는 '태연'이었다.
😥문제점:
Non Repeatable Read ,이외에 Phantom Read 문제도 발생
REPEATABLE READ에서는 위와 같이 자신의 트랜잭션 번호(10) 보다 높은 트랜잭션 번호(12)에서 변경된 레코드는 UNDO 영역에 백업된 레코드를 읽게 된다.
위와 같이 트랜잭션 2 내에서 SELECT COUNT(*)-전체 행의 개수를 구하는 쿼리의 결과가 달라질 수 있다.
=> 트랜잭션 1에서 INSERT 쿼리를 수행한 결과가 트랜잭션 2에게 보이기 때문
헬창 백엔드 개발자의 이것저것 블로그 님의 글을 참조하여 작성하였습니다.
code-lab1님의 글을 참조하여 작성하였습니다.