[ CS / DataBase ] Transaction

xx0hn·2022년 1월 21일
0

CS

목록 보기
15/47

Transaction

트랜잭션은 여러 개의 수행이 일련의 처리 단위로 묶여 작업의 완전성을 보장해주는 것이다. 만약에 하나의 작업을 위해 3개의 작은 작업들이 돌아가야 한다면 트랜잭션은 이 3개의 작은 작업이 모두 성공적으로 완료되어야만 큰 하나의 작업을 끝낼 수 있도록 해준다. 만약 작은 3개의 작업 중 하나라도 실패를 한다면 바로 이전의 작은 작업들을 실행하기 전으로 되돌려준다. 이는 사용자 입장에서는 작업의 논리적 단위로 이해할 수 있고, 시스템의 입장에서는 데이터들을 접근 또는 변경하는 프로그램의 단위가 된다.

Transaction 특성


트랜잭션은 ACID라는 4가지 특성을 가진다.

Atomicity (원자성)

트랜잭션 중간에 문제가 발생할 경우 트랜잭션에 해당하는 어떠한 작업 내용도 수행되어서는 안되며 아무런 문제가 발생하지 않았을 때에만 모든 작업이 수행되어야 한다.

즉, 하나의 트랜잭션에 묶인 여러 수행들은 하나의 수행처럼 이뤄져야 한다.

Consistency (일관성)

트랜잭션이 완료된 다음에도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성이 유지되어야 한다.

Isolation (고립성)

각각의 트랜잭션은 서로의 간섭없이 독립적으로 수행되어야 한다.

Durability (지속성)

트랜잭션이 정상적으로 완료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 유지되어야 한다.

Transaction 상태

  • Active
    트랜잭션 활동 상태, 실행중인 상태
  • Failed
    트랜잭션 실패 상태로, 더 이상 정상적으로 진행할 수 없는 상태
  • Partially commited
    트랜잭션의 Commit 명령이 도착한 상태.
    (SQL문이 완료 되고 Commit만 남은 상태를 의미)
  • Committed
    트랜잭션 완료 상태, 트랜잭션이 정상적으로 완료된 상태
  • Aborted
    트랜잭션 취소 상태, 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태

Partially committed & Committed

Commit 요청이 들어오면 Partially committed는 상태가 된다. 이후 Commit을 문제없이 수행할 수 있다고 판단되면 Committed 상태로 전이되고, 만약 Commit을 하기 전에 오류가 발생하면 Failed 상태로 전이된다.

Transaction 사용 주의점

트랜잭션은 반드시 필요한 상황에서만 최소한으로 적용해야 한다. 이는 트랜잭션 범위의 최소화를 의미한다. 데이터베이스의 커넥션 수는 정해져 있는데, 각각의 단위 프로그램이 커넥션을 오랫동안 소지하고 있게 되면 사용 가능한 커넥션의 개수가 줄어들게 되고 이 상황이 반복될 경우 사용 가능한 커넥션을 위해 기다려야 하는 경우가 발생할 수도 있다.

Lock

Lock은 트랜잭션 처리의 순차성을 보장하기 위한 방법이다. 트랜잭션이 순차적으로 처리되도록 함으로써 손실된 업데이트를 방지하는데 중요한 역할을 하고, 자동으로 발생한다. Lock을 통해 데이터에 대한 일관성 유지, 동시 사용이 가능해진다.

Shared Lock (Read Lock, 공유 락)

데이터를 읽을 때 사용되어지는 Lock이다. 데이터를 읽을 때에는 데이터의 변경이 발생하지 않기 때문에 Shared Lock끼리는 같은 데이터에 동시에 접근이 가능하다.

Exclusive Lock (Write Lock, 베타 락)

데이터를 변경하고자 할 때 사용되는 Lock으로 트랜잭션이 완료될 때까지 유지된다. Exclusive Lock이 해제될 때까지 다른 트랜잭션은 해당 리소스에 접근할 수 없다. 그리고 다른 트랜잭션이 수행되고 있는 데이터에 대하여 함께 Lock을 설정할 수 없다.

Blocking


블로킹은 Lock 간의 경합이 발생하여 특정 트랜잭션이 작업을 진행하지 못하고 멈춰있는 상태를 말한다. 이때의 두 Lock은 베타-베타 혹은 베타-공유 이다. 공유-공유 간에는 블로킹이 발생하지 않는다. 블로킹을 해소하기 위해서는 이전의 트랜잭션이 완료되어야 한다. 이전의 트랜잭션으로 인해 그 다음 트랜잭션이 접근하지 못하고 자신의 순서를 기다리는 것이다. 블로킹은 성능에 좋지 않은 영향을 미치기 때문에 DB를 사용하는 프로그래밍을 진행할 때에는 다음과 같은 부분을 주의해야한다.

  • 하나의 트랜잭션의 길이를 너무 길게하는 것은 블로킹의 확률을 높인다.
  • 초기 설계 시 같은 데이터를 갱신하는 트랜잭션이 동시 수행되지 않도록 해야 한다.
  • 트랜잭션의 격리성 수준을 과하게 상향 조정하지 않아야 한다.
  • 적절한 튜닝을 통해 쿼리의 성능을 높인다.

Dead Lock (교착 상태)


교착 상태는 두 개의 트랜잭션이 각각의 하나씩의 리소스에 Lock을 건 상태로 서로의 리소스에 접근하여 값을 얻어오려 할 때에 각각의 Lock에 의해 양쪽 트랜잭션이 결국은 서로를 끝없이 기다리는 현상을 말한다. 이렇게 되면 프로그램이 아무일도 하지 못하고 멈춰버리게 된다.

Dead Lock 빈도를 줄이는 법

  • 트랜잭션을 자주 커밋한다.
  • 정해진 순서로 테이블에 접근한다. 트랜잭션이 모두 같은 순서로 테이블에 접근한다면 Dead Lock을 줄일 수 있다.
  • 공유 Lock의 사용을 피한다.
  • 한 테이블의 복수 행을 복수의 연결에서 순서 없이 갱신하면 교착상태가 발생하기 쉽다. 테이블 단위의 Lock을 통해 갱신을 직렬화하면 동시성은 떨어지지만 Dead Lock를 줄일 수 있다.
profile
개발 일기

0개의 댓글