4 minute read

트랜잭션 제어와 세션

🌺 트랜잭션 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)

⭐ 직렬화 가능 기능 ▶️ 격리 수준 완화!

ANSI 표준 격리 수준의 분류

⭐ 가장 이상적인 격리 수준의 보장은 Serializable!!

⚠️ BUT!! Serializable 수준은 DBMS 운영시 동시성이 크게 떨어지면서 성능상 이슈 발생 ▶️ Serializalbe보다 낮은 격리 수준으로 DBMS가 운영됨으로써 많은 문제가 발생됨(아래에서 확인 가능!!)

격리 수준 완화되면서 직렬화 가능에서 없었던 현상 발생과 각 격리 수준 간의 관계

격리 수준 완화로 직렬화 가능에서 없었던 현상의 발생

격리 수준과 3가지 현상의 관계

⭕ : 가능 , ❌ : 불가능

락의 개념과 유형, 데드락

🌺 락 LOCK

  • 데이터를 수정 중이라는 사실을 알리는 방법의 잠금 장치!!
  • 생신 손실 문제를 해결하기 위해서 필요한 상대방 트랜잭션의 데이터 사용 여부를 알 수 있는 규칙!

🌺 락의 종류

① 공유락 LS; Shared Lock

  • 트랜잭션이 읽기를 할 때 사용하는 락

② 배타락 LX; Exclusive Lock

  • 트랜잭션이 읽고 쓰기를 할 때 사용하는 락

🌷 공유락과 배타락을 사용하는 규칙

공유락과 배타락을 사용하는 규칙

  1. 데이터에 락이 걸려있지 않으면, 트랜잭션은 데이터에 락을 걸 수 있다!
  2. 트랜잭션이 데이터 X를 “읽기만 할 경우”, LS 요청
  3. 트랜잭션이 데이터 X를 “읽거나 쓰기를 할 경우”, LX 요청
  4. 다른 트랜잭션이 데이터에 읽기 요청 LS(X)를 걸어두었다면, LS(X)요청만 허용!
  5. 다른 트랜잭션이 데이터에 LX(X)를 걸어두었다면, 다른 LS 혹은 LX 요청 모두 허용하지 않음!
  6. 트랜잭션이 락을 허용받지 못하면 대기 상태(HANG)가 됨!

🌷 데드락 =”교착 상태”

  • 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대해서 락을 획득하고, 상대방 데이터에 대해서 락을 요청하여 무한 대기 상태에 빠질 수 있게 되는 현상
  • DBMS는 일반적으로 두 개의 트랜잭션이 있을 때, 데드락(교착 상태)가 발생되면, 하나의 작업은 강제중지하고 나머지 하나만 정상작동되도록 함! 이 때 중지되는 트랜잭션에서 변경한 데이터는 원래 데이터로 되돌려 놓음!
  • 서로 상대 테이블에 잠금 필요한 처리를 실행하기 위해서 아무리 대기하더라도, 상황은 한 명이 양보하기 전까지 절대로 풀릴 수 없음

⭐ 데드락을 최소화시키는 DBMS 전반적 대책!!

  1. 트랜잭션을 자주 커밋
  2. 정해진 순서로 테이블에 액세스하도록 하기
  3. 필요없는 경우에는 읽기 잠금 획득 사용을 피하기
  4. 쿼리에 의한 잠금 범위를 좁히거나 더 작은 것으로 하기
  5. 한 테이블의 복수 행을 순서 변경없이 갱신하면 교착 상태 발생 쉬움
  6. 테이블 단위 잠금 획득하여 갱신 직렬화하기

⭐ 자제해야 하는 트랜잭션 처리

  1. AutoCommit(JDBC 부분에서 Connection 객체.setAutoCommit(false); 부분 관련)
    • 쿼리 단위로 커밋하는 설정
    • 애플리케이션 잠금 실행 시 Commit의 부하가 너무 높음
  2. 긴 트랜잭션
    • 트랜잭션 동시성 , 자원 유효성을 저하시킬 수 있음
    • 타임아웃 및 교착상태 발생 가능
    • UNDO 로그 크기 과도화
    • 시스템 요건 따라 동시 실행 커넥션 수를 적절히 설정
  3. 트랜잭션 관련 설정 확인
    • 시스템 요건 및 애플리케이션 로직에 맞추어 트랜잭션 격리 수준 조정
    • 예상되는 오류에 대처 가능한 형태로 애플리케이션 작성해야 함

✴️ 행 레벨 록 Row Level Rock

  • 데이터가 테이블의 특정 행 데이터일 경우 해당 행만 LOCK이 발생되는 경우

✴️ 테이블 레벨 록 Table Level Rock

  • WHERE 절로 제한을 두지 않고 진행하는 DML에서 발생될 수 있는, 테이블 단위의 잠금

COMMIT, ROLLBACK, SAVEPOINT

https://github.com/hy6219/TIL-Today-I-Learned-/blob/main/Database/Oracle/Basic/Transaction%20Control%20Language.png?raw=true

Transaction Control Language

TCL은 위의 그림으로 간단하게 이해해볼 수 있다!

  • 가로로 그어진 점선은 색상에 상관없이 하나의 트랜잭션이라고 이해하면 된다!
  • 그리고 TCL은 노란 상자로 구분해두었다!

위의 그림을 바탕으로 이해해볼 때,

  • COMMIT: 데이터베이스에 결과를 영구하게 저장
  • SAVEPOINT : 원하는 시점의 결과를 영구하게 저장하는 것이 아니라, ROLLBACK을 하기 위한 임시저장 상태를 표시해두는 것
  • ROLLBACK: 트랜잭션을 취소

한다는 점을 확인해볼 수 있다!

⭐ 같은 데이터베이스를 사용할 경우, 락의 문제가 있을 수 있으므로!! 꼭! 작업 후에는 COMMIT이나 ROLLBACK으로 리소스를 해제시켜주자!!

Updated: