[데이터베이스] 트랜잭션, ACID

hyyyynjn·2021년 9월 2일
0

면접대비

목록 보기
7/31
post-thumbnail

Q. 트랜잭션에 대해 설명해주세요

트랜잭션이란 데이터베이스의 상태를 변화시키는 하나의 논리적인 작업 단위이다.
트랜잭션에는 여러 개의 연산이 수행될 수 있고, 수행중에 한작업이라도 실패하면 전부를 rollback하고 모두 성공해야 commit한다.

Q. ACID에 대해 설명해주세요

ACID는 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질이다.

  • Atomicity(원자성) : 트랜잭션의 연산은 모든 연산이 완벽히 수행되어여 하며, 한 연산이라도 실패하면 트랜잭션은 실패해야한다.
  • Consistency(일관성) : 트랜잭션은 유효한 상태로만 변경될 수 있다.
  • Isolation(고립성) : 트랜잭션은 동시에 실행될 경우 다른 트랜잭션에 의해 영향을 받지 않고 독립적으로 실행되어야 한다.
  • Durability(내구성) : 트랜잭션이 커밋된 이후에는 시스템 오류가 발생하더라도 커밋된 상태로 유지되는 것을 보장해야 한다. (비휘발성 메모리에 데이터가 저장되는 것을 의미한다.)

✅트랜잭션

BEGIN TRANSACTION
update sqldelete sql...
COMMIT TRANSACTION

DBMS에서 데이터베이스를 다루는 하나의 논리적인 작업이다.

  • 데이터베이스에서 데이터를 다루는 작업이 일어날 때 장애가 발생하는 경우, 올바르게 데이터를 복구하는 작업 수행의 논리적 단위트랜잭션으로 삼는다.
  • 데이터베이스에서 프로그램이 동시에 실행될 때, 프로그램들을 서로 분리하는 단위이다.
    • 트랜잭션은 쿼리를 하나의 묶음으로 처리하여 수행하고, 수행중에 실행이 중단된 경우 Rollback을 수행하고 오류 없이 실행을 마치면 Commit을 수행한다.
      • Commit 연산 : 한개의 논리적 단위(트랜잭션)에 대한 작업이 성공적으로 끝났고 데이터베이스가 다시 일관된 상태에 있을 때, 이 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산
      • Rollback 연산 : Rollback 연산은 하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때, 이 트랜잭션의 일부가 정상적으로 처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산

1부터 6까지 일어나는 게 하나의 트랜잭션이다.

📢트랜잭션의 목적

사용자가 데이터베이스의 완전성 (Integrity)를 유지하기 위함이다. (다른 말로 데이터 부정합을 방지하기 위함이다)

  • 데이터 부정합 의 예시
    • DB 서버에 여러 개의 클라이언트가 동시에 접근하거나 응용프로그램이 갱신을 처리하는 고정에서 중단되는 경우
  • 데이터 부정합을 막기 위해서 프로세스를 병렬로 처리하지 않도록 해야하지만 이는 효율이 매우 떨어진다
    👉 프로세스를 병렬로 처리할 수 밖에 없는 현실적 상황에서 데이터 부정합을 방지하기 위해 트랜잭션을 사용하는 것이다.

📢트랜잭션과 프로그램의 차이

트랜잭션프로그램
구조BEGIN TRANEND TRANmain(){..}
데이터데이터베이스에 저장된 데이터를 다룬다데이터를 다루거나 다루지 않을 수 있다. 데이터를 다룰 때 파일에 저장된 데이터를 다룬다
번역기DBMS가 번역한다컴파일러가 번역한다
성질ACID

✅ACID

트랜잭션이 안전하게 수행되는 것을 보장하기 위해 갖추어야할 성질이다.

  • 👏Atomicity (원자성)
    트랜잭션의 연산은 모든 연산이 완벽히 수행되어여 하며, 한 연산이라도 오류가 발생하면 트랜잭션 전부가 취소되어야 한다.
    • All or Nothing의 개념으로서 작업 단위 일부분만 실행하지 않는다는 것을 의미한다.
  • 👏Consistency (일관성)
    트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지한다.
    • 고정요소는 트랜잭션 수행 전과 완료 후의 상태가 같아야 한다.
  • 👏Isolation (고립성)
    둘 이상의 트랜잭션 수행시 다른 트랜잭션의 연산 작업이 끼어들 수 없다. (수행중인 트랜잭션이 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.)
  • 👏Durability (지속성, 내구성)
    성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다는 것을 의미한다. (비휘발성 메모리에 데이터가 저장되는 것을 의미한다.)
    • commit을 하면 현재 상태는 영원히 보장된다는 것을 의미한다.

📢원자성 보장

수행하고 있는 트랜잭션에 의해 변경된 내역을 유지하면서 이전에 commit된 상태를 임시 영역에 따로 저장함으로써 보장한다. 다시말해, 현재 수행하고 있는 트랜잭션에서 오류가 발생하면 현재 내역을 날리고 임시 영역에 저장했던 상태로 rollback 한다.

  • 이전 데이터들이 임시로 저장된 영역을 Rollback Segment 라고 한다.
    👉 트랜잭션의 원자성은 Rollback Segment에 의해 보장된다.
  • 현재 수행하고 있는 트랜잭션에 의해 새롭게 변경되는 내역을 Database Table이라고 한다.
질의 수행
savepoint A
질의 수행
rollback to A

트랜잭션의 길이가 길어지면 확실하게 오류가 발생하지 않은 부분도 처음부터 다시 작업을 수행해햐되는 비효율성 문제가 생긴다. 따라서 확실한 부분에 대해서는 rollback이 되지 않도록 Save Point (중간 저장 지점)을 지정한다.

Save Point를 지정하면 rollback할 때 지정된 save point 이후부터 진행하게 된다.

📢일관성 보장

트랜잭션 수행 전후에 데이터 모델의 모든 제약 조건 (기본키, 외래키, 도메인, 도메인 제약조건 등)을 만족하는 것을 통해 보장한다.

테이블B기본키 (b_id)테이블A외래키 (b_id) 로 존재할 경우, b_id에 대한 제약조건이 테이블B에서 변경되면 b_id를 외래키로 가지는 테이블A에서도 변경되어야 한다.

  • 이벤트와 조건이 발생할 떄 트리거 (Trigger)를 통해 트랜잭션 일관성을 보장한다.

📢고립성 보장

✍병행 처리

CPU가 여러 프로세스를 처리하는 것처럼, 트랜잭션에 정해진 시간을 할당해서 작업을 하다 부여된 시간이 끝나면 다른 트랜잭션을 실행하는 방식으로 트랜잭션을 조금씩 처리하는 것을 말한다.

예를 들어, 트랜잭션A에서 데이터 x를 100으로 설정한 뒤 시간이 만료되어 트랜잭션B로 넘어갔다고 가정하자.
트랜잭션B는 데이터 x에 -50 연산을 해서 저장한뒤 시간이 만료되어 트랜잭션A로 넘어가면 트랜잭션A에서 의도한 값과 다른 데이터 x값을 얻게 된다.

👉 트랜잭션의 병행 처리로 인해 트랜잭션 간의 간섭이 일어날 경우 갱신분실, 오손파독, 반복불가능, 팬텀문제 가 발생하기 때문에 트랜잭션 고립성이 보장되어야 한다.

✍고립성 보장 방법

OS의 Semaphore와 비슷한 개념으로 Lock & Unlock을 통해 트랜잭션의 고립성을 보장할 수 있다.

  • 데이터를 읽거나 쓸 때는 다른 트랜잭션이 접근하지 못하도록 Lock을 하고, 수행을 마치면 Unlock으로 다른 트랜잭션이 데이터에 접근할 수 있도록 허용한다.
  • 데이터를 읽을 때, 여러 트랜잭션이 읽을 수 있도록 허용하는 shared_lock (공유 락)을 사용한다. (데이터 쓰기는 허용하지 않고 읽기만 가능)
  • 데이터를 쓸 때, 다른 트랜잭션이 읽지도 쓰지도 못하도록 하는 exclusive_lock (배타 락)을 사용한다.

lock & unlock을 잘못 사용하면 모든 트랜잭션이 아무것도 수행할 수 없는 데드락 (Deadlock) 상태에 빠질 수 있다.

트랜잭션의 데드락을 막기위해 2PL 프로토콜 규칙에 의해 고립성을 보장해야 한다.

✍2PL 프로토콜

여러 트랜잭션이 공유하고 있는 데이터에 동시에 접근할 수 없도록 하기 위한 목적의 프로토콜이다.

locking에는 상승 단계 (growing phase)하강 단계 (shrinking phase) 라는 2가지 단계가 존재한다.

  • 상승 단계 : read_lock, write_lock
  • 하강 단계 : unlock
    👉 2PL 프로토콜상승 단계하강 단계가 섞이면 안된다는 것을 의미한다.

lockunlock이 번갈아 수행되면 안되고 lock이 쭉 수행된 후 unlock이 쭉 수행된어야 한다는 프로토콜이다.


📌 정리하면, 성능을 위해 트랜잭션을 병렬 처리해야 하는데, 트랜잭션의 고립성을 보장하기 위해서 2PL 프로토콜을 사용해야 한다.

0개의 댓글