42_[db]트랜잭션 제어와 세션
트랜잭션 제어와 세션
🌺 트랜잭션 Database Transaction
- 데이터베이스 관리 시스템(DBMS; Database Management System) 또는 유사한 시스템에서 상호작용의 최소 수행 단위
- 유사한 시스템 = 트랜잭션의 성공 및 실패가 분명하고 상호 독립적 ➕ 트랜잭션의 결과가 일관적이고 그에 대해 믿을 수 있는 시스템
⭐ TCL; Transaction Control Language : 트랜잭션 제어를 위해 사용되는 명령어
🌺 트랜잭션의 특징
- 트랜잭션 조작하는 기능 : 사용자가 DB의 완전성(Integrity) 유지에 대한 확신을 가질 수 있도록 함
- 단일 트랜잭션 : DB 내에 읽거나 쓰는 여러 개 쿼리를 요구! 중요한 것은 DB가 수행된 일부 쿼리가 남지 않아야 함!! 트랜잭션은 서로 간섭하지 않아야!!
- 쿼리 하나가 실패하면, 데이터베이스 시스템은 전체 트랜잭션 또는 실패한 쿼리를 롤백!!
ⓐ 원자성 Atomicity - 데이터 조작이 전부 성공 또는 실패할 지 보증하는 구조 ▶️ 이러한 특징으로 인해서 “ALL OR NOTHING”으로 트랜잭션이 설명되고는 함!
- COMMIT: 조작 과정에 문제 없으면 처리 확정
- ROLLBACK : 조작 중간에 문제 발생 시 첫 과정 직전으로 복귀
ⓑ 일관성 Consistency - 데이터 조작 전후 일관성 유지 필요
- 데이터베이스 오브젝트에 정합성 제약 추가 가능(데이터간의 모순 없이 일치)
세션 Session: 데이터베이스 접속을 시작으로 다양한 DB 작업 후 접속을 종료하기까지 전체 기간
- 세션 내에는 하나 이상의 트랜잭션이 존재 ⭐ (개념적으로) 세션 > 트랜잭션
읽기 일관성 - 특정 세션에서 테이블의 데이터를 변경 중일 때, 그 외 다른 세션에서는 데이터 변경이 확정되기 전까지는 특정 세션에서 수정되고 있는 데이터가 아닌, 본래의 데이터(=변경이 적용되기 전의 데이터)를 읽을 수 있는 특성 ▶️ 데이터에 대한 비일관성 발생!
ⓒ 고립성 Isolation(격리성) - 복수 사용자가 동시에 데이터 조작을 하는 상황이 구현되는 경우, 각 사용자의 요청에 대한 처리가 모순없이 실행되는 것을 보증
- 복수의 트랜잭션이 순서대로 실행되는 경우와 같은 결과( ↔️ 직렬화 가능). 데이터베이스 오브젝트에 대해 잠금을 걸어 후속 처리를 차단 ➕ DBMS 내에서 트랜잭션 격리 수준 설정으로 구현됨(ANSI 표준 격리 수준(직렬화 가능 기능으로 인해서 격리 수준이 완화되었음)
ⓓ 지속성 Durability - 데이터 조작 완료 후 완료 통지를 받는 시점에서 결과를 잃지 않는 것
-
시스템 장애 경우에도 조작이 영구성을 가져야 함
-
트랜잭션 조작을 하드디스크에 로그로 기록하고, 시스템 이상 발생 시 로그를 이용해 복구
🌺 트랜잭션 격리 수준
#1.ANSI 표준 격리 수준(Isolation level)
⭐ 직렬화 가능 기능 ▶️ 격리 수준 완화!
⭐ 가장 이상적인 격리 수준의 보장은 Serializable!!
⚠️ BUT!! Serializable 수준은 DBMS 운영시 동시성이 크게 떨어지면서 성능상 이슈 발생 ▶️ Serializalbe보다 낮은 격리 수준으로 DBMS가 운영됨으로써 많은 문제가 발생됨(아래에서 확인 가능!!)
격리 수준 완화되면서 직렬화 가능에서 없었던 현상 발생과 각 격리 수준 간의 관계
⭕ : 가능 , ❌ : 불가능
락의 개념과 유형, 데드락
🌺 락 LOCK
- 데이터를 수정 중이라는 사실을 알리는 방법의 잠금 장치!!
- 생신 손실 문제를 해결하기 위해서 필요한 상대방 트랜잭션의 데이터 사용 여부를 알 수 있는 규칙!
🌺 락의 종류
① 공유락 LS; Shared Lock
- 트랜잭션이 읽기를 할 때 사용하는 락
② 배타락 LX; Exclusive Lock
- 트랜잭션이 읽고 쓰기를 할 때 사용하는 락
🌷 공유락과 배타락을 사용하는 규칙
- 데이터에 락이 걸려있지 않으면, 트랜잭션은 데이터에 락을 걸 수 있다!
- 트랜잭션이 데이터 X를 “읽기만 할 경우”, LS 요청
- 트랜잭션이 데이터 X를 “읽거나 쓰기를 할 경우”, LX 요청
- 다른 트랜잭션이 데이터에 읽기 요청 LS(X)를 걸어두었다면, LS(X)요청만 허용!
- 다른 트랜잭션이 데이터에 LX(X)를 걸어두었다면, 다른 LS 혹은 LX 요청 모두 허용하지 않음!
- 트랜잭션이 락을 허용받지 못하면 대기 상태(HANG)가 됨!
🌷 데드락 =”교착 상태”
- 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대해서 락을 획득하고, 상대방 데이터에 대해서 락을 요청하여 무한 대기 상태에 빠질 수 있게 되는 현상
- DBMS는 일반적으로 두 개의 트랜잭션이 있을 때, 데드락(교착 상태)가 발생되면, 하나의 작업은 강제중지하고 나머지 하나만 정상작동되도록 함! 이 때 중지되는 트랜잭션에서 변경한 데이터는 원래 데이터로 되돌려 놓음!
- 서로 상대 테이블에 잠금 필요한 처리를 실행하기 위해서 아무리 대기하더라도, 상황은 한 명이 양보하기 전까지 절대로 풀릴 수 없음
⭐ 데드락을 최소화시키는 DBMS 전반적 대책!!
- 트랜잭션을 자주 커밋
- 정해진 순서로 테이블에 액세스하도록 하기
- 필요없는 경우에는 읽기 잠금 획득 사용을 피하기
- 쿼리에 의한 잠금 범위를 좁히거나 더 작은 것으로 하기
- 한 테이블의 복수 행을 순서 변경없이 갱신하면 교착 상태 발생 쉬움
- 테이블 단위 잠금 획득하여 갱신 직렬화하기
⭐ 자제해야 하는 트랜잭션 처리
- AutoCommit(JDBC 부분에서 Connection 객체.setAutoCommit(false); 부분 관련)
- 쿼리 단위로 커밋하는 설정
- 애플리케이션 잠금 실행 시 Commit의 부하가 너무 높음
- 긴 트랜잭션
- 트랜잭션 동시성 , 자원 유효성을 저하시킬 수 있음
- 타임아웃 및 교착상태 발생 가능
- UNDO 로그 크기 과도화
- 시스템 요건 따라 동시 실행 커넥션 수를 적절히 설정
- 트랜잭션 관련 설정 확인
- 시스템 요건 및 애플리케이션 로직에 맞추어 트랜잭션 격리 수준 조정
- 예상되는 오류에 대처 가능한 형태로 애플리케이션 작성해야 함
✴️ 행 레벨 록 Row Level Rock
- 데이터가 테이블의 특정 행 데이터일 경우 해당 행만 LOCK이 발생되는 경우
✴️ 테이블 레벨 록 Table Level Rock
- WHERE 절로 제한을 두지 않고 진행하는 DML에서 발생될 수 있는, 테이블 단위의 잠금
COMMIT, ROLLBACK, SAVEPOINT
Transaction Control Language
TCL은 위의 그림으로 간단하게 이해해볼 수 있다!
- 가로로 그어진 점선은 색상에 상관없이 하나의 트랜잭션이라고 이해하면 된다!
- 그리고 TCL은 노란 상자로 구분해두었다!
위의 그림을 바탕으로 이해해볼 때,
- COMMIT: 데이터베이스에 결과를 영구하게 저장
- SAVEPOINT : 원하는 시점의 결과를 영구하게 저장하는 것이 아니라, ROLLBACK을 하기 위한 임시저장 상태를 표시해두는 것
- ROLLBACK: 트랜잭션을 취소
한다는 점을 확인해볼 수 있다!
⭐ 같은 데이터베이스를 사용할 경우, 락의 문제가 있을 수 있으므로!! 꼭! 작업 후에는 COMMIT이나 ROLLBACK으로 리소스를 해제시켜주자!!