일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 삽입 이상
- MSA
- 삭제 이상
- null
- 스레드 풀
- gatway
- HTTP
- Dirty Checking
- Kotlin
- buildSrc
- 3-way handshaking
- 네트워크
- ocp
- 자바
- DB
- 정규화
- java
- well-know port
- JPA
- 자료구조
- 데이터베이스
- AWS
- 캐시 오염
- Spring
- 비관적 락
- 낙관적 락
- 갱신 이상
- Redis
- 페이지네이션
- Kafka
- Today
- Total
어 나 갱수.
[DB] Transaction의 모든 것 ✌🏾 본문
오늘은 Transaction에 대해 알아보겠습니다. ✌🏾
트랜잭션이란?
데이터베이스의 상태를 변경시키는 단위, 한 번에 수행되어야 하는 연산들이라고 정리하면 좋을 거 같습니다.
상태를 변경시킨다?
SELECT, INSERT, DELETE, UPDATE 등과 같은 DML문을 사용하는 것을 의미합니다.
논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든 것이 트랜잭션입니다.
트랜잭션의 SQL문중에서 일부의 SQL만 성공해서 일부의 내용만 DB에 반영되는 일을 방지해 줍니다.
트랜잭션은 각각의 SQL에 대한 결과를 상황에 따라 두 가지로 나뉩니다. commit(커밋)과 rollback(롤백)입니다.
- commit(커밋) : 하나의 트랜잭션 단위에 있는 모든 SQL문이 다 성공했을때 변경사항들을 DB에 반영합니다.
- rollback(롤백) : 트랜잭션 단위에 있는 SQL문 중 하나라도 실패하면 모든 변경사항들을 되돌리는 작업입니다.
트랜잭션을 왜 사용?
ATM으로 계좌이체를 한다고 가정해 보겠습니다.
1. A계좌에는 현재 100만 원이 있고 B계좌에는 현재 50만 원이 있습니다.
2. A계좌에서 B계좌로 50만 원을 보냈습니다.
3. A계좌에서는 50만 원이 빠져나가 100만원에서 50만원이 되었습니다.
4. B계좌에서 받은 50만 원을 기존 계좌에서 추가하려는 작업을 하다가 오류가 나서 B계좌에는 입금이 되지 않는 상황이 발생했습니다.
5. A계좌에서는 돈이 빠져나갔지만 B계좌에는 돈이 들어오지 않는 상황이 발생했습니다.
위와 같은 상황에서 저 모든 작업들이 하나의 트랜잭션 안에서 작동하였다면 중간에 오류가 발생해서 rollback이 발생해 모든 작업이 처음 상태로 되돌아갔을 겁니다. 하지만 트랜잭션안에서 작동하지 않았다면 기존 A계좌에서만 돈이 빠져나가게 되는 상황이 발생하게 될 겁니다.
이러한 상황을 방지하고자 트랜잭션은 필요한 작업입니다.
트랜잭션의 특징
트랜잭션에는 4가지의 특징이 있습니다. Atomicity, Consitency, Isolation, Durability 이렇게 4가지가 존재하고 앞글자를 따서
ACID라고 불립니다.
원자성(Atomicity)
- 트랜잭션의 작업이 부분적으로 실행되거나 중단되는 것을 보장하지 않는다.
- 트랜잭션 단위에 있는 모든 작업은 다 같이 DB에 반영되거나 다 같이 반영되지 않아야 합니다.
트랜잭션에서 원자성은 수행하고 있는 트랜잭션에 의해 변경되는 내용들을 저장하면서, 이전에 commit 되어서 DB에 반영된 상태를 임시 저장을 함으로써 보장합니다. 만약 현재 수행 중인 트랜잭션에서 오류가 나서 rollback을 해야 하는 상황이 발생한다면 현재 트랜잭션에서 변경되고 있던 내용을 다 삭제하고 이전에 commit 된 DB의 상태로 되돌립니다.
이전의 commit된 DB상태를 저장하는 곳을 롤백 세그먼트(rollback segment)라고 합니다.
일관성(Constency)
- 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다.
- 만약 제약 조건을 위반한다면 트랜잭션은 중단된다.
트랜잭션 실행 후에도 데이터베이스의 제약이나 규칙을 만족시켜 일관성을 유지해야 한다는 의미이다.
예를 들어 계좌 테이블에서 '계좌의 돈은 항상 양수여야 한다.'라는 제약 조건이 있다면 그 제약조건에 맞게 DB에 저장하도록 해야 한다.
transaction이 DB에서 정의된 rule을 위반했는지 DBMS가 커밋하기 이전에 확인하고 알려준다.
일관성을 보장하기 위해 트리거를 사용합니다.
트리거(Trigger)
- 특정 테이블에서 INSERT, DELETE, UPDATE와 같은 DML문이 수행되었을 때 데이터베이스에서 자동으로 바뀐 정보로 저장하는 작업을 해주는 프로그램입니다. 사용자가 직접 호출하는 것이 아닌 데이터베이스에서 자동으로 호출합니다.
격리성(Isolation)
- 트랜잭션 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.
- 둘 이상의 트랜잭션이 동시에 병행 실행될 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 낄 수 없습니다.
격리성을 보장하기 위해서는 Lock & Unlock 기법을 사용합니다.
Lock & Unlock
데이터를 읽거나 쓰기 작업 중일 때는 Lock을 걸어서 다른 트랜잭션이 접근 못하게 하고, 먼저 시작된 트랜잭션의 요청이 끝나면 Unlock을 하여 다른 트랜잭션이 처리될 수 있도록 허용하는 방식을 통해 격리성을 보장할 수 있습니다.
지속성(Durability)
- 성공적으로 트랜잭션이 완료되어 commit 된 정보들은 데이터베이스에 영원히 반영이 되어야 합니다.
- 시스템 장애 또는 전원 손실과 같은 예상치 못한 상황이 발생하더라도, 데이터베이스는 영구적으로 변경된 상태를 유지해야 한다.
트랜잭션의 상태
트랜잭션은 논리적으로 5가지 상태를 가지고 있다.
1. 활성(Active) : 트랜잭션이 정상적으로 실행 중인 상태를 의미한다.
트랜잭션이 시작되면, 해당 트랜잭션의 상태는 활동(Active) 상태가 된다.
2. 부분완료(Partially Committed) : 트랜잭션의 마지막 연산까지 실행되었지만, Commit 연산이 이루어지기 직전의 상태
3. 완료(Commited) : 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태
설계된 트랜잭션대로 명령을 성공적으로 수행한다면 그다음 상태는 부분적 완료(Partially committed) 상태가 된다.
설계된 트랜잭션의 연산이 성공하였다고 해서 무조건 반영하는 것이 아니라, 설계자의 최종승인(Commit)이 있을 때까지 실제 데이터베이스에 반영하지 않고 기다리고 있는 상태이다.
설계자가 작업 결과에 대하여 반영을 승인(Commit)한다면 트랜잭션이 성공적으로 종료된다(committed).
4. 실패(Failed) : 트랜잭션 실행 중 오류가 발생하여 중단된 상태.
5. 철회(Aborted) : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태.
트랜잭션을 수행하는 중간에 오류가 발생하여 실행이 중단된 상태를 실패라고 한다.
이때 트랜잭션이 비정상적으로 종료되었으니, 트랜잭션 내부의 작업을 이전 상태로 되돌리는 롤백(Rollback)을 수행하면 그 상태를
철회(Aborted)라고 한다.
이번에는 Transaction이 무엇이고 왜 필요한지 알아보았는데요. 다음에는 Spring Boot에서 Transaction이 어떻게 사용되는지 알아 보도록 하겠습니다. 긴 글 읽어주셔서 감사합니다.