트랜잭션이란 ?
데이터베이스 시스템에서 여러작업을 하나의 단위로 묶어서 처리하는 것
데이터베이스의 일관성을 유지하기 위해서 중요하며, 주로 금융이나 전자상거래, 재고 관리 시스템등에서 사용한다.
트랜잭션의 주요 특징 (ACID)
(1) 원자성 Atomicity
- 트랜잭션 내의 모든 작업들이 모두 성공하거나, 모두 실패해야 한다는 것을 의미함
- 트랜잭션이 중간에 실패하면 그 트랜잭션이 수행한 모든 변경 사항들이 취소되어야함.
ex) 은행에서 A계좌에서 출금해서 B계좌로 입금한다고 가정했을때,
A계좌에서 출금은 되고 B 계좌로 입금이 실패했을 경우, 시도했던 모든 동작들을 실패로 돌리는 것이 트랜잭션 원자성을 만족하는 것이다.
(2) 일관성 Consistency
- 트랜잭션이 성공적으로 완료되면, 데이터베이스는 일관된 상태를 유지해야한다
- 트랜잭션이 시작되기 전과 완료된 후에 데이터베이스는 정의된 모든 규칙을 충족해야한다.
+ 데이터 베이스에서 master DB와 slave DB 간의 데이터가 같게 유지하는 것도 트랜잭션 일관성인가?하는 생각이 들었는데 찾아보니까 그건 "데이터 동기화 일관성"을 유지하는 것이라고 볼 수 있겠다.
master DB와 slave DB간의 데이터 동기화 일관성을 유지하고, 여기서 트랜잭션 개념이 들어가려면
master DB에서만, 트랜잭션이 비즈니스 규칙을 위반하지 않도록 데이터 무결성 제약조건을 만족시키는 것을 트랜잭션의 일관성을 유지한다. 라고 볼 수 있다.
(3) 고립성 Isolation
- 모든 트랜잭션은 독립적으로 실행되어야하고, 다른 트랜잭션의 영향을 받으면 안된다.
- 동시에 트랜잭션이 실행된다면, 서로의 중간 상태를 볼 수 없다.
+ 트랜잭션이 동시에 실행될때는 고립성을 유지하기 위해 다양한 기법을 사용하는데, (real mysql에 나오는 내용!!)
1. 잠금
- 공유 잠금 : 여러 트랜잭션이 동시에 데이터를 읽을 수 있도록 허용하지만, 데이터를 수정하는 것은 허용하지 않음
- 베타 잠금 : 한 트랜잭션이 데이터를 수정할 때 다른 트랜잭션이 해당 데이터에 접근하지 못하도록 함
- 정합성 수준 설정 : SQL 표준에서는 고립성을 관리하기 위해 여러 격리 수준을 정의함.
2. 멀티버전 동시성 제어(MVCC)
- MVCC는 데이터의 여러버전을 유지하여 트랜잭션 간의 충돌을 방지함.
- 읽기 작업은 스냅샷을 사용하고, 쓰기 작업은 데이터의 최신 버전에만 사용. (언두영역?)
정합성 수준 설정 : SQL 표준에서는 고립성을 관리하기 위해 여러 격리 수준을 정의함. => 트랜 잭션의 격리 수준
1. Read Uncommitted: 트랜잭션이 커밋되지 않은 데이터를 읽을 수 있음. 가장 낮은 격리수준으로 더티리드 발생o
2. Read Committed:다른 트랜잭션이 커밋한 데이터만 읽을 수 있음. 더티리드 발생x 지만, Non-repeatable Read 발생o
3 . Repeatable Read
: 동일 트랜잭션 내에서 같은 데이터를 여러번 읽을 때 항상 같은결과를 보장함. 더티리드 발생x, Non-repeatable Read 발생x, 팬텀리드 발생o
=> mysql의 InnoDB엔진이 이 격리수준을 사용함.
4. Serializable : 가장 높은 격리수준으로 ,모든 트랜잭션이 순차적으로 실행되는 것 처럼 보이게 하는 것.
더티리드 발생x, Non-repeatable Read 발생x, 팬텀리드 발생x 지만, 동시성이 가장 낮다.
(4) 영속성,지속성 Durability
- 트랜잭션이 완료된 후에는 시스템 장애가 발생하더라도 그 결과가 데이터베이스에 영구적으로 반영되어야함.
- 보통 로그를 통해 보장되는 편이다.
=> 금융이나 전자상거래 처럼 돈이 오가는 상황에서 가장 잘 알아야하는 개념 같다.
=> 트랜잭션을 사용할때 SQL에서는 BEGIN, ROLLBACK, COMMIT 명령어를 사용한다.
BEGIN;
-- 계좌 A에서 100달러 인출
UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';
-- 오류 발생, 예를 들어 계좌 B가 존재하지 않는 경우
IF (/* some error condition */) THEN
ROLLBACK;
-- 트랜잭션 종료
ELSE
-- 계좌 B에 100달러 입금
UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';
COMMIT;
END IF;