은행에서 A에서 B로 송금을 하려고 한다고 할때, A에서 돈을 빠져나갔지만 B로 입금이 되지 않았을 경우를 생각해보겠습니다.
이럴 때 A의 송금을 취소하거나, B의 계좌에 따로 송금을 시켜주면 되지만, 이러한 과정은 너무 번거롭고 위험합니다.
이러한 문제를 해결하기위해서 모든 거래가 완벽하게 끝난 후에만 거래가 완료 된것으로 승인하기로 했습니다.
만약 중간에 오류가 발생했을때에는 송금을 하기 이전에 상태로 되돌려놓는 것입니다.
이러한 방식으로 거래의 안정성을 확보할 수 있습니다.
이러한 방식을 위해 트랜잭션이 필요합니다.트랜잭션의 종류
활동 : 트랜잭션이 수행중인 상태를 의미합니다.
실패 : 트랜잭션이 오류로 인해 중단된 상태를 의미합니다.
부분완료 : 트랜잭션이 모든 연산을 실행했지만, commit되기 이전임을 나타냅니다.
완료 : 트랜잭션이 모두 정상적으로 처리되었고 이를 DB에 영구적으로 저장하는 작업입니다.
철회 : 트랜잭션의 처리중 문제점을 확인하고 이를 취소하는 상태입니다
트랜잭션은 ACID라는 특성을 갖고 있습니다.
만약 ACID의 원칙을 엄격하게 지킨다면 동시성이 떨어지게 되고 이는 비효율적입니다. 때문에 이러한 동시성을 확보하기 위해서 ACID의 원칙(독립성)을 희생하는 방법이 존재합니다.
이 방법을 Transaction의 격리수준 이라고 합니다.
격리 수준 : 동시에 여러 트랜잭션이 처리될때 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용하는 정도를 결정하는 것을 말합니다.
고립정도가 심해진다면 성능은 저하되는 것입니다.
격리 수준을 설정해서 어디까지 Lock을 설정할 것인지 자동으로 정해지는 것입니다.
격리 수준이 뭐가 좋다 나쁘다는 정할 수 없습니다. 어떤 전략으로 데이터를 다루도록 하는지가 중요합니다.
Lock 이란, DB에 여러 사용자들이 접근하는 상황에서 세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에 커밋이나 롤백 전까지 다른 세션에서 해당 데이터를 수정할 수 없게 막는 역할을 합니다.
- 트랜잭션의 특성인 독립성을 지켜줍니다.
- 수정 뿐만 아니라 조회할때도 Lock 을 사용할 수 있는데, 이때 select for update 구문을 사용해서 Lock을 획득합니다.
- 예를 들어서 돈과 관련된 계산을 진행할때 다른 곳에서 금액을 변경하지 못해서 Lock을 가져갑니다.
Lock의 범위
- 데이터베이스 : 전체 DB를 기준으로 Lock을 설정
- 잘 사용하지 않지만, DB 업데이트나 소프트웨어 버전 업그레이드에 사용
- 파일 : 파일을 기준으로 Lock을 설정
- 파일이란, 테이블, row 등 과 같은 데이터가 쓰여지는 장소를 의미
- 잘 사용되지는 않습니다.
- 테이블 : 테이블을 기준으로 Lock을 설정
- 전체 테이블에 영향을 줄때 주로 사용합니다. ex) DDL 사용 => 때문에 DDL Lock이라고도 합니다.
- 페이지와 블럭 : 파일의 일부인 페이지와 블록을 기준으로
- 잘 사용하지 않습니다.
- 컬럼 : 컬럼을 기준으로 Lock을 설정
- 이 범위는 리소스(자원)가 많이 들기에 잘 사용하지 않습니다.
- 행 : DML에 대해 가장 기본적으로 사용하는 Lock
블로킹이란, Lock들 끼리 경합이 발생해서 특정 세션이 작업을 진행하지 못하고 멈춘 상태를 의미합니다. 즉, 상대 Lock이 끝나기를 기다리고있는 것입니다.
- 공유 락 - 배타 락
- 배타 락 - 배타 락
위와 같은 블로킹이 발생할 수 있습니다.해결방법
- 이를 해결하는 방법은 트래잭션을 commit과 rollback해주는 것과 SQL문장이 빠르게 실행되도록 리팩토링 하는 것
교착상태란, 두 트랜잭션이 각각 Lock 을 설정하고 서로의 lock에 접근해서 값을 얻어려고 할때 트랜잭션이 commit, rollback 되기전까지 기다려야하는데 이때 양쪽의 트랜잭션이 엉켜서 서로 영원히 처리가 되지 않는 상태를 의미합니다.
- 공유 락 - 베타 락
- 배타 락 - 배타 락
위와 같은 데드락이 발생할 수 있습니다.해결방법
- 예방 : 교착 상태 발생 조건 중 하나를 제거해서 예방합니다.
- 단점 : 자원 낭비가 심합니다.
- 회피 : 데드락 발생할 위험이 있는 자원이 생기면 자원 할당 요청을 보류합니다.
- 자원을 할당한 후에도 안정 상태로 남아있는가를 확인합니다.
- 단점 : 오버헤드(특정 기능을 수행하는데 드는 자원)가 많이 발생한다.
- 탐지 : 빠르게 데드락을 발견하고 문제를 해결합니다.
- 회복 : 교착 상태를 일으킨 프로세스를 종료하거나 할당된 자원을 해제합니다.
블로킹과 교착상태는 뭐가 다를까?
블로킹은 락끼리의 경합상태시 트랜잭션의 진행이 멈춰있는 현상을 말한다고 했습니다. 때문에 경합중인 트랜잭션들 중에서 하나의 트랜잭션이 일을 끝내고 commit한다면 이어서 다른 트랜잭션이 실행될 수 있는 것입니다. 때문에 영원하지 않습니다.
하지만, 교착상태는 서로가 서로의 트랜잭션을 기다리는 상태이기 때문에 영원히 끝나지 않습니다.