트랜잭션 = '업무실행단위'로서 준비된 쿼리들이 '하나인 것마냥' 처리해주는 것
처리되려면 반드시 4가지를 염두해야함 (ACID)
1) Atomicity
- 원자성
- 쿼리 2개가 반만 실행되거나 한 개만 실행되거나 이러면 안 됨
- 쿼리가 다 실행되거나 or 아예 실행되지 않거나
-> commit, rollback으로 유지 가능
2) Consistency
- 일관성
- 데이터 결함이 발생하는 트랜잭션이 처리되어서는 안되는 것
-> 제약 조건, 프로그램 로직으로 전체 쿼리가 실행되는 과정에서 잘못된 부분을 제어해야함
3) Isolation
- 고립성 / 독립성
- ex) 두 개 이상이 실행되다보니..
만약 두 유저가 동시에 접속했다면
A, B Thread가 업데이트중인데 A가 작업중인데 B가 중간에 업데이트하거나 삭제하거나 그러면 A가 엉망징창 됨
-> lock 걸어서 설정해줌. (A가 작업할 동안 B가 건드리지 못하게)
4) Durability
- 지속성
- Commit 실행되면 영구적으로 잘 저장되어 있어야 한다는 점 (심지어 전기가 나갈 때조차)
-> log 파일 이용해서 중간 과정을 껴 넣음
전기가 만약에 나가면 log 파일을 확인해서 db에 적용되었는지 확인한 후 안되어 있으면 넣는 식으로 영속성 유지
* Isolation을 알아보자 *
https://www.roseindia.net/tutorial/java/jdbc/jdbcisolationlevels.html
4가지의 고립도를 설정 가능
상황 가정 : A가 먼저 선점하고 B가 뒤따라 진행하는 녀석이라고 해보자.
1. READ_UNCOMMITTED
- lock을 가장 안 건 레벨
- (A가 작업 중이더라도 B가) 작업 중인 데이터를 읽을 수 있는 것
근데 그게 dirty reads/phantom reads 가 될 수 있다는 것 (데이터가 A에 의해서 변경될 가능성이 높으니)
(둘 다 commit되지 않은 데이터를 읽어옴으로서 생기는 문제)
dirty reads - commit, rollback할지 모르는 데이터를 읽어온 것
phantom reads - 읽어왔더니 없는...!
원래는! A가 commit하지 않으면 'hello'를 B가 읽을 수 없지
근데 1번으로 read_uncommited라고 고립도를 낮추면! A가 commit을 안하더라도 B가 읽을 수 있는 상황
- 먼저 선점한 A가 Rollback해버리면 B가 title="hello"라고 읽고, 업데이트하고, 수정하고, 삭제하던 그 데이터는...where is "hello"가 되어버리는 상황인 것
- A가 rollback 해버리면 B는 A가 적용하려다가 만 데이터를 만든 것 (안 읽어도 될 값을 읽은 것. dirty한 값을 읽은 것)
Q. 굳이 고립도를 왜 낮출까?
- 유연성을 주기 위해...
- 그리고 B의 행동이 (dirty-reads) 그렇게 치명적이지는 않음
그래서 성능을 높이는 쪽을 선택한 것 (사용자 입장에서는 '내가 뭘 본거지?' 정도 수준이라고)
- 문제가 되면 그 때 가서야 lock을 높이는 쪽으로 (우선은 성능!)
2. READ_COMMITTED
- commit된 것만 읽게 해주는 것
- 근데 그런데도 문제가 된다.
non-repeatable reads / phantom reads 발생 가능
- dirty reads는 발생하지 않으나 ... 다시 읽을 수 없는 문제가 발생할 수 있는 것 (다른 얘가 수정, 삭제한 것들을 commit해버리면 이전의 내용을 읽을 수 없으니)
-> lock을 건다. (3번!)
3. REPEATABLE_READ
- 무조건 한 쪽이 기다려야 함
3번과 4번의 차이는
작업중인 데이터 단위는 '레코드'
내가 작업한 레코드 단위에 대해서는 다른 사람은 손대지 못하는것
- 근데 100개 중 내가 작업하는게 3개라면 나머지 97개는 열려져 있는 것
4. SERIALIZABLE
- 반면 4번은 테이블을 잠가버려서 100개를 다 잠가버리는 것
굉장히 고립도가 높으나 성능은 최악
// 3번이 기본 고립도로 설정되어 있다.
* 적용을 해보자 *
con 객체에서 metaData 얻어내서
/ isolation 레벨을 설정하고 바꿀 수 있음
3번인걸 굳이 바꿀 필요는 x
나중에 문제 생기면 그때서야 lock을 높이거나 줄이거나 하는게 옳다.
ㅡㅡㅡㅡㅡ
원자성 처리는
con 객체 만들고 / autoCommit을 (false)로 하고 commit 하는 것
ㅡㅡㅡㅡㅡ
durabilty는 운영자가 관리할 부분이라 프로그래머가 신경 쓸 필요는 x
가장 많이 신경 쓰는 건 '원자성'
그 예제를 해보려 했으나... (프로젝트) 업무적으로 생겼을 때 하도록 하겠다.
64일 - 트랜잭션 (Transaction. feat. 64일차 총 복습 메모) (0) | 2021.05.21 |
---|---|
64일 - 시퀀스 (Sequence) (0) | 2021.05.21 |
61일차. DB 14 - 모델링 (2정규화, 4정규화, 제약조건 - 도메인(NOT NULL, DEFAULT, CHECK), 엔티티(PRIMARY KEY, UNIQUE)) (0) | 2021.05.17 |
60일차. DB 13 - 모델링 (논리설계 실습) (1) | 2021.05.14 |
59일차. DB 12 - 모델링 (개념설계 실습) (0) | 2021.05.13 |