데이터베이스 트랜잭션

갱두·2021년 10월 6일
0

📚 데이터베이스

목록 보기
4/9

트랜잭션이란 무엇인가?

트랜잭션은 작업의 완전성을 보장해주는 것이다.
즉, 논리적인 작업셋을 모두 완벽하게 처리하거나 또는 처리하지 못할 경우에는 원 상태로 복구해서 작업의 일부만 적용되는 현상이 발생하지 않게 만들어주는 기능이다.

사용자의 입장에서는 작업의 논리적 단위로 이해를 할 수 있고 시스템의 입장에서는 데이터들을 접근 또는 변경하는 프로그램의 단위가 된다.

트랜잭션과 Lock

- 잠금 : 동시성을 제어하기 위한 기능
- 트랜잭션 : 데이터의 정합성을 보장하기 위한 기능

✔️ 데이터 무결성 : 데이터 값이 정확하고 완전해야 한다
-> 즉, 말이 안되는 데이터가 있으면 안된다.
✔️ 데이터 정합성 : 서로 모순이 없이 일관되게 일치해야 한다
-> 즉, 어떤 데이터들의 값이 서로 일치해야 한다.

🔒 잠금 : 여러 커넥션에서 동시에 동일한 자원(레코드나 테이블)을 요청할 경우, 순서대로 한 시점에는 하나의 커넥션만 변경할 수 있게 해주는 역할을 한다.
🔒 트랜잭션 : 하나의 논리적인 작업 셋 중 하나의 쿼리가 있든,, 두 개 이상의 쿼리가 있든 관계없이 논리적인 작업 셋 자체가 100% 적용되거나 아무것도 적용되지 않아야 함을 보장하는 것이다.

트랜잭션의 특성

트랜잭션은 ACID라는 4가지의 특성을 만족해야 한다.

1. 원자성 (Atomicity)
트랜잭션 중간에 어떠한 문제가 발생한다면 트랜잭션에 해당하는 어떠한 작업 내용도 수행되어서는 안되고, 아무런 문제가 발생하지 않았을 경우에만 모든 작업이 수행되어야 한다.
2. 일관성 (Consistency)
트랜잭션이 완료된 다음의 상태에서도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장해야 한다.
3. 고립성 (Isolation)
각각의 트랜잭션은 서로 간섭없이 독립적으로 수행되어야 한다.
4. 지속성 (Durability)
트랜잭션이 정상적으로 종료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 저장되어야 한다.

트랜잭션의 상태


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

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

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

Commited
트랜잭션이 정상적으로 완료된 상태를 말함

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

✅ Partially committed & Committed의 차이점

Commit 요청이 들어옴 -> Partially Commited

  • Commit을 문제 없이 수행할 수 있음 -> Committed
  • 오류가 발생함 -> Failed

즉, Committed 는 Commit 요청이 들어왔을 때, Committed는 Commit을 정상적으로 완료한 상태를 말함

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

트랜잭션은 꼭 필요한 최소한의 코드에만 사용하는 것이 좋다.

왜 ? 🤷🏻‍♀️

일반적으로 데이터베이스 커넥션은 개수가 제한적이다. 그런데 각 단위 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어들게 됨. 그러다가 어느 순간에는 각 단위 플그램에서 커넥션을 가져가기 위해 기다려야 하는 상황이 발생할 수 있기 때문

교착 상태(Deadlock)

교착 상태란 무엇인가

교착 상태란 두 개 이상의 트랜잭션이 특정 자원의 Lock을 획득한 채로 다른 트랜잭션이 소유하고 있는 Lock을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태를 말함.

MySQL에서의 교착상태의 예씨

MySQL MVCC에 따른 특성 때문에 트랜잭션에서 갱신 연산(Insert, Update, Delete)를 실행하면 Lock을 획득함
✅ MVCC(Multiversion concurrency control, 다중 버전 동시성 제어)
동시 접근을 허용하는 데이터베이스에서 동시성을 제어하기 위해 사용하는 방법 중 하나이다.

  • 일반적인 RDBMS보다 매우 빠르게 작동 (Lock을 필요로 하지 ❌)
  • 사용하지 않는 데이터가 계속 쌓이게 되므로 데이터를 정리하는 시스템이 필요

트랜잭션 1이 테이블 B의 첫번째 행의 Lock을 얻고, 트랜잭션 2도 테이블 A의 첫번째 행의 Lock을 얻었다고 하자.
트랜잭션을 commit 하지 않은 채 서로의 첫번째 행에 대한 Lock을 요청하면

Transaction 1> insert into A values(1);
Transaction 2> insert into B values(1);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

Deadlock이 발생한다.

Deadlock의 빈도를 낮추는 방법

  • 트랜잭션을 자주 커밋한다.
  • 정해진 순서로 테이블에 접근한다.
    위에서 트랜잭션1이 테이블 B->A의 순으로 접근했고, 트랜잭션2는 테이블 A->B로 접근함 -> ❌ 트랜잭션들이 동일한 테이블 순으로 접글할 수 있도록
  • 읽기 Lock 획득의 사용을 피한다 (SELECT ~ FOR UPDATE)
profile
👩🏻‍💻🔥

0개의 댓글