업데이트:

트랜잭션, Transaction

트랜잭션은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 수행되어야 할 일련의 연산들을 의미한다.

💡 상태 변환? SELECT, INSERT, UPDATE, DELETE 와 같은 질의어를 통해 DB에 접근하는 것

이 때 작업의 단위는 SQL 명령문 하나가 아닌 논리적 단위, 즉 많은 명령문들을 사람이 정하는 기준에 따라 정해진다.

트랜잭션의 특징, ACID

트랜잭션은 이론적으로 아래와 같은 성질을 갖고 있지만, 성능향상을 위해 종종 완화되는 경우가 있다고 한다.

Atomicity — 원자성

✅ 트랜잭션이 데이터베이스에 모두 또는 전혀 반영되지 않아야 한다.

✅ 트랜잭션 내의 모든 명령은 반드시 완벽히 수행(Commit)되어야 하며 그렇지 않을 경우 트랜잭션 전부가 취소(Rollback)되어야 한다.

Consistency — 일관성

✅ 트랜잭션의 작업 처리 결과는 항상 일관성 있어야 한다.

✅ 시스템이 가진 고정요소는 트랜잭션 수행 전과 완료 후의 상태가 같아야 한다.

Isolation — 독립성

✅ 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다.

✅ 수행 중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.

Durability — 영구성

✅ 트랜잭션이 성공적으로 완료되었을 경우 결과는 영구적으로 반영되어야 한다.

트랜잭션의 연산

Commit

하나의 트랜잭션이 성공적으로 끝나서 DB가 일관성 있는 상태일 때 하나의 트랜잭션이 끝났음을 알려주기 위해 사용한다.

Rollback

하나의 트랜잭션 처리가 비정상적으로 종료되어 DB의 일관성이 깨졌을 때, 트랜잭션의 일부가 정상적으로 처리되었더라도 원자성을 만족시키기 위해 모든 연산을 취소할 때 사용한다.

Save Point

작업 전체를 취소하는 롤백과는 달리 특정 부분에서 트랜잭션을 취소하기 위해 사용한다. 트랜잭션 중간 단계에서 세이브포인트를 지정해 트랜잭션을 작게 분할하는 것이 가능하다.

트랜잭션의 상태

트랜잭션은 아래 5가지의 상태로 구분할 수 있다.

🔎 활동 Active : 트랜잭션이 실행중이며 동작중인 상태

🔎 실패 Failed : 트랜잭션이 더 이상 정상적으로 진행될 수 없는 (중단된) 상태

🔎 철회 Aborted : 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태

🔎 부분 완료 Partially Committed : 트랜잭션의 마지막 연산이 수행되고 Commit 연산만 남은 상태

🔎 완료 Committed : 트랜잭션이 성공적으로 종료되어 Commit 연산을 수행한 상태

부분완료와 완료

Commit 요청이 들어오면 부분완료 상태가 되고, 이후에 Commit 연산을 문제 없이 수행 할 수 있다면 완료 상태, 없다면 실패 상태가 된다.

트랜잭션의 스케줄

직렬 스케줄, Serial Schedule

하나의 트랜잭션 실행이 완료되면 다른 트랜잭션을 시작하는 방식으로 순서대로, 하나씩 실행하는 스케줄이다. 따라서 트랜잭션이 실행되는 동안 다른 트랜잭션의 영향을 받지 않는다.

참고: 병행제어

필요성

다수의 사용자가 데이터베이스에 요청을 보낼 때, 직렬 스케줄 방식이라면 처리 시간이 매우 오래 걸릴 것이다. 따라서 병행처리 방식을 사용하는데 이는 처리 효율은 높아지지만 처리 과정에서 동일한 자료를 동시에 접근해 오류가 발생할 수 있다.

문제점

🔎 업데이트 유실 문제 : 두 트랜잭션이 동시에 동일한 자료를 갱신 — 첫째 갱신 유실

🔎 임시 업데이트 문제 : 갱신하는 도중에 다른 트랜잭션이 읽기 — 이전 자료 읽기

🔎 잘못된 요약 : 두 자료를 갱신(sum, max, …)하는 도중에 읽기 — 요약 결과 오류

🔎 무결성 제약조건 : 두 자료의 제약조건을 검사하지 않고 갱신 — 일관성 위반

위와 같은 문제를 방지하기 위해 충돌 스케줄을 찾아 직렬화 스케줄을 만드는 것이 트랜잭션 스케줄의 목적이다.

직렬화 스케줄, Serializable Schedule

병행제어와 직렬 스케줄의 장점을 가진 스케줄로, 트랜잭션들이 동시에 자료 접근 연산들을 교차하며 실행시키지만 결과는 직렬 스케줄과 동일한 스케줄이다. 즉, 병행처리 하지만 적절한 제어 조치를 취해 일관성을 유지하는 스케줄이다.

록킹 기법

록킹 기법이란 자료를 배타적으로 접근하는 방법으로 공유 록과 배타 록 2가지가 있다.

공유 록 Shared Lock

특정 자료에 공유 록을 건다면 다른 트랜잭션은 이 자료를 갱신할 수 없다. 공유 록이 걸린 자료는 다른 트랜잭션에 의해서 읽혀질 수 있다.

배타 록 Exclusive Lock

배타 록은 트랜잭션이 자료를 기록할 때 걸어야 하며 배타 록을 가진 트랜잭션은 자료를 읽고, 갱신할 수 있다. Dirty Read를 방지하기 위해 공유 록을 가진 트랜잭션들은 배타 록이 걸린 자료를 읽을 수 없다.

💡 Dirty Read: 변경 후 아직 Commit 되지 않은 값을 읽고, Rollback 후의 값을 다시 읽어 최종 결과 값이 상이한 현상

댓글남기기