트랜잭션
논리적인 작업 셋이 100% 적용되거나, 아무것도 적용되지 않아야함을 보장해주는 것. → 작업의 완전성을 보장한다(일부 업데이트가 되지 않음.)
부분 업데이트 (Partial Update)
중간에 오류가 발생하면 발생 전 상태를 롤백하지 않고 놔두는 것. → 테이블 데이터의 정합성을 맞추는데 상당히 어려운 문제를 만든다.
주의할 점
범위를 최소화하기. 꼭 필요한 최소의 코드에만 적용해라!
- DB 커넥션은 개수가 제한적이라 각 단위 프로그램이 커넥션을 소유하는 시간이 길어지면 사용 가능한 여유 커넥션의 개수는 줄어든다.
- DB 를 조회하는 등의 작업을 굳이 넣을 필요는 없겠다.
- 네트워크를 통해 원격 서버와 통신하는 작업은 어떻게든 DBMS 의 트랜잭션 내에서 제거해라!
- 중간에 통신 오류가 나면 웹 서버뿐 아니라 DBMS 서버까지 위험!
- 사용자가 입력한 정보를 저장하는 등의 작업은 하나의 트랜잭션으로.
- 성격이 다른 작업은 별도의 트랜잭션으로 분리하는 것이 좋다.
트랜잭션의 격리 수준 Isolation Level
여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 말지를 결정하는 수준.
격리 수준
DIRTY READ | NON-REPEATABLE READ | PHANTOM READ | |
READ UNCOMMITTED | 발생 | 발생 | 발생 |
READ COMMITTED | 없음 | 발생 | 발생 |
REPEATABLE READ | 없음 | 없음 | 발생 |
SERIALIZABLE | 없음 | 없음 | 없음 |
4개의 격리 수준에서 순서대로 뒤로 갈 수록 데이터 격리(고립) 정도가 높아지며, 동시 처리 성능도 떨어진다.
→ 하지만, SERIALIZABLE 수준이 아니라면 크게 성능 개선이나 저하는 발생하지 않는다.
READ UNCOMMITTED
commit, rollback 여부와 상관없이 다른 트랜잭션에서 보인다.
쿼리 실행 도중 알 수 없는 문제가 발생해 INSERT 된 내용을 롤백해도 다른 트랜잭션은 그게 정상적인 데이터라고 생각하고 계속 처리할 수 있다. DIRTY READ 발생.
더티 리드 DIRTY READ
어떤 트랜잭션에서 처리한 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상
✅ 최소한 READ COMMITTED 이상의 격리 수준을 사용하자.
READ COMMITTED
어떤 트랜잭션에서 데이터를 변경해도 commit 이 완료된 데이터만 다른 트랜잭션에서 조회 가능.
변경 내용이 커밋되기 전까지는 다른 트랜잭션에서 변경 내역을 조회할 수 없다.
커밋이 되기만 하면 한 트랜잭션 내에서도 다른 select 결과가 뜰 수 있다.
→ “REAPETABLE READ “ 정합성에 어긋난다.
리피터블 리드 REPEATABLE READ
하나의 트랜잭션 내에서 똑같은 select 쿼리를 실행했을 때 항상 같은 결과를 가져와야 한다.
REPEATABLE READ
트랜잭션 안에서 실행되는 모든 select 쿼리는 트랜잭션 번호가 자기 번호보다 작은 트랜잭션 번호에서 변경한 것만 보게 된다. → 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
문제점
- 서버 처리 성능이 떨어짐 모든 트랜잭션은 고유한 트랜잭션 번호를 가지며 언두 영역에 백업된다. 그런데 한 사용자가 begin 으로 트랜잭션을 시작하고 장시간 트랜잭션을 종료하지 않으면 언두 영역이 백업 데이터로 무한정 커질 수도 있다!
- 데이터 부정합 A가 insert 를 실행하는 도중, B가 select ~ for update 를 실행하고 A의 insert 가 커밋된 후, B가 다시 select 하면, 첫 번째 select 와 다른 값의 데이터가 보인다.
팬텀 리드 PHANTOM READ
다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안 보였다 하는 현상.
SERIALIZABLE
한 트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 절대 접근할 수 없음.
- 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야 한다.
- 다른 격리 수준보다 동시 처리 성능이 떨어진다.
'개발공부 개발새발 > DB' 카테고리의 다른 글
DB ) 잠금(MySQL 기준) (0) | 2023.08.18 |
---|---|
DB ) 인덱스 (0) | 2023.08.08 |
MyBatis ) 마이바티스 스프링 부트 연동하기 (1) | 2023.01.15 |
JPA ) JPA 요약 (내가 검색하는 용도) (2) | 2022.11.29 |
JPA ) 여러가지 값 타입~ (0) | 2022.11.25 |