트랜잭션이란 


트랜잭션은 여러 개의 수행이 일련의 처리 단위로 묶이는 것을 말한다.

위 그림은 왼쪽 계좌의 돈을 오른쪽 계좌로 입금하는 과정이다.
첫번 째처럼 왼쪽 계좌에서 출금이 성공되면 오른쪽 계좌로 입금된다.
ATM의 문제로 왼쪽에서 출금이 되고 몇 분 후, 출금이 취소되었다고 하면 두번째 그림처럼 오른쪽 계좌에도 입금이 되지 않아야한다.

만약 출금은 취소 되었는데 입금이 돼버리면 큰 기능상의 문제인 것이다.
이렇게 일련의 처리가 All or Nothing으로 이루어지는 것이 트랜잭션이다.
  • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위
  • 상태를 변화 시킨다 =  SQL 질의어를 통해 DB에 접근한다 
    • SELECT INSERT DELETE UPDATE
  • 작업 단위 ---> 많은 SQL 명령문들을 사람이 정하는 기준에 따라 정하는 것
    •  게시판에서 사용자가 글을 작성하고 올리기 버튼을 누른 후 게시판에 다시 돌아오면 게시판에 내가 쓴 글이 업데이트된 상태를 볼 수 있다.
      • 이때 DB 작업
        • 올리기 버튼을 누른다. : INSERT문을 사용해 사용자가 입력한 게시글 데이터를 옮김.
        • 게시판 새로 구성 : SELECT문을 사용해 최신 정보를 유지.
      • 현재 작업 단위  INSERT 문 + SELECT 문 -----------> 이를 통틀어 하나의 tranaction이라 한다!

즉. 하나의 트랜잭션 설계를 잘 만드는 것이 데이터를 다룰 때 많은 이점을 준다.

 

작업의 완전성 을 보장해주는 것이다. 즉, 논리적인 작업 셋을 모두 완벽하게 처리하거나 또는 처리하지 못할 경우에는 원 상태로 복구해서 작업의 일부만 적용되는 현상이 발생하지 않게 만들어주는 기능이다. 사용자의 입장에서는 작업의 논리적 단위로 이해를 할 수 있고 시스템의 입장에서는 데이터들을 접근 또는 변경하는 프로그램의 단위가 된다.

 

 

 

 

 

트랜잭션의 Commit, Rollback 연산


Commit

 이란 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관성있는 상태에 있을 때, 하나의 트랜잭션이 끝났다라는 것을 알려주기위해 사용하는 연산이다.

이 연산을 사용하면 수행했던 트랜잭션이 로그에 저장되며, 후에 Rollback 연산을 수행했었던 트랜잭션단위로 하는것을 도와준다.

 

 

Rollback

이란 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진경우, 트랜잭션을 처음부터 다시 시작하거나, 트랜잭션의 부분적으로만 연산된 결과를 다시 취소시킨다.

후에 사용자가 트랜잭션 처리된 단위대로 Rollback을 진행할 수도 있다.

 

 

 

 

트랜잭션 특징 ACID


ACID 4가지 특성을 만족해야한다.

 

1. 원자성(Atomicity)

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

 

2. 일관성(Consistency)

트랜잭션이 완료된 다음의 상태에서도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장해야 한다.

 

3. 고립성(Isolation)

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

 

4. 지속성(Durability)

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

 

 

 

 

 

트랜잭션의 상태


 

Active

트랜잭션의 활동 상태. 트랜잭션이 실행중이며 동작중인 상태를 말한다.

 

Failed

트랜잭션 실패 상태. 트랜잭션이 더이상 정상적으로 진행 할 수 없는 상태를 말한다.

 

Partially Committed

트랜잭션의 Commit 명령이 도착한 상태. 트랜잭션의 commit이전 sql문이 수행되고 commit만 남은 상태를 말한다.

 

Committed

트랜잭션 완료 상태. 트랜잭션이 정상적으로 완료된 상태를 말한다.

 

Aborted

트랜잭션이 취소 상태. 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태를 말한다.

 

Partially Committed 와 Committed 의 차이점

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

즉, Partial Commited는 Commit 요청이 들어왔을때를 말하며, Commited는 Commit을 정상적으로 완료한 상태를 말한다.

 

 

 

 

잠금


■ 잠금(Locking)이란 ?

- 여러 사용자가 동일한 시간에 동일한 데이터를 동시에 액세스할 수 있게 해준다.

- 잠금은 트랜잭션을 순차적으로 처리되도록 함으로써 손실된 업데이트를 방지하는데 중요한 역할을 하며 자동으로 발생한다.

- 잠금을 통해 데이터에 대한 일관성 유지와 동시 사용이 가능해진다.

 

 

 

 ■ 블로킹(Blocking)이란 ?

- 어떤 프로세스가 자원을 엑세스하려고 할 때 이미 다른 프로세스가 그 자원을 잠그고 있어서 그 잠금이 풀릴 때까지 기다려야 하는 상황을 말한다. 이러한 차단이 오랫동안 유지될 경우 문제가 된다.

 

 

 

■ 잠금 관리

- 교착상태(Dead Locks) :

  * 트랜잭션 A는 트랜잭션 B가 원하는 데이터를 잠그고 있으면서 트랜잭션 B가 잠그고 있는 데이터를 원한다.

  * 트랜잭션 B는 트랜잭션 A가 원하는 데이터를 잠그고 있으면서 트랜잭션 A가 잠그고 있는 데이터를 원한다.

- MSSQL 해결방법 : 한쪽 트랜잭션 처리를 강제로 종료(비용이 적은 트랜잭션의 처리를 강제 종료한다.)

- SET DEADLOCK_PRIORITY 문을 사용해 교착 상태 발생 시 트랜잭션의 중요도를 지정할 수 있다.

- 우리 회사의 경우 sp_mon_blocking 프로시저를 이용해 블로킹 상태인 spid를 찾아낸다. 블로킹하고 있는 spid 세션을 죽이기 위해 ' kill [spid] ' 명령어를 사용한다.

 

 

 

트랜잭션을 사용할 때 주의할 점


트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다. 즉 트랜잭션의 범위를 최소화하라는 의미다.

 

일반적으로 데이터베이스 커넥션은 개수가 제한적이다.

그런데 각 단위 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어들게 된다.

그러다 어느 순간에는 각 단위 프로그램에서 커넥션을 가져가기 위해 기다려야 하는 상황이 발생할 수도 있는 것이다.

 

 

교착상태

교착상태란 무엇인가
복수의 트랜잭션을 사용하다보면 교착상태가 일어날수 있다. 교착상태란 두 개 이상의 트랜잭션이 특정 자원(테이블 또는 행)의 잠금(Lock)을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태가 되는데, 이를 교착상태라고 한다.

 

 

 

교착상태의 빈도를 낮추는 방법

  • 트랜잭션을 자주 커밋한다.
  • 정해진 순서로 테이블에 접근한다. 위에서 트랜잭션 1 이 테이블 B -> A 의 순으로 접근했고, 트랜잭션 2 는 테이블 A -> B의 순으로 접근했다. 트랜잭션들이 동일한 테이블 순으로 접근하게 한다.
  • 읽기 잠금 획득 (SELECT ~ FOR UPDATE)의 사용을 피한다.
  • 한 테이블의 복수 행을 복수의 연결에서 순서 없이 갱신하면 교착상태가 발생하기 쉽다, 이 경우에는 테이블 단위의 잠금을 획득해 갱신을 직렬화 하면 동시성을 떨어지지만 교착상태를 회피할 수 있다.

 


Reference.

link1 link2 link3

+ Recent posts