트랜젝션이 뭔데요?

Haribo·2022년 7월 7일
1

1일 1cs

목록 보기
1/9
post-thumbnail

어디서 들어봤는데 뭐였지?

이번에 1일 1cs 비서라는 카카오 플친 기능을 누군가 구현해 놨길래 그 동안 놓았던 cs 지식도 쌓을겸 공부해보고 있다. 처음으로 받았던 질문은 바로 이것.

트랜잭션에서의 데드락이란 무엇이고 그 해결방법을 설명해주세요.

거짓말 안치고 다 까먹었다. (ㅋㅋ) 무조건 알고 있어야 했던 개념인데 이걸 잊다니 너무 나태해졌다. 뭔지 바로 알아보도록 하자.

트랜젝션 🤔

이것은 작업의 완전성을 보장해 주는 것이다. 다른 말로는 논리적인 작업을 모두 완벽하게 처리하거나 하지 못했다면 복구하여 작업의 일부만 적용되는 현상을 방지한다. 이것이 사용자 입장에선 작업의 논리적 단위로 이해가 가능하고 시스템 입장에선 데이터들을 접근 또는 변경하는 프로그램 단위가 된다.

말이 복잡한데 풀어 쓰자면
데이터베이스는 항상 절차적으로 스크립트를 처리해 나간다. 그 와중 한 부분이 잘못 됐을 시 그동안 진행했던 것들을 없던 일로 만들고 복구한다. 즉, 이상한 부분을 건너 뛰거나 그 부분만 복구해서 진행하지 않는다.

가장 설명하기 쉬운 예시로 송금 시스템이 있다.

트랜젝션의 특성들 👾

이를 ACID라고 하는데 각각의 앞 글자를 따서 만들었다.

💫 원자성(Atomicity)
=> 만약 트랜잭션 중간에 문제가 발생한다면 그에 해당하는 어떠한 작업 내용도 수행되면 안된다. 즉, 아무런 문제가 없는 경우에만 모든 작업이 수행 되어야 한다.

💫 일관성(Consistency)
=> 트랜잭션이 완료된 다음의 상태에서도 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장해야한다. (밥을 먹고 난 후와 먹기 전의 태도가 다르면 안된다)

💫 고립성(Isolation)
=> 각각의 트랜잭션은 서로 간섭없이 독립적이어야 한다.

💫 지속성(Durability)
=> 트랜잭션이 정상적으로 종료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 저장되야 한다.

트랜잭션은 꼭 여러 개의 변경 작업을 수행하는 쿼리가 조합되었을 때만 의미있진 않다. 하나의 논리적인 작업 셋 중 하나의 쿼리가 있든 두 개 이상이 있든 관계없이 논리적인 작업 셋 자체가 100% 적용되거나 아무것도 적용되지 않아야 함을 보장한다. 쉽게 예를 들면 HW 에러 또는 SW 에러와 같은 문제로 인해서 작업에 실패가 있을 경우 특별한 대책이 필요한데 이러한 것을 해주는 것이다.

사용할때 주의할 점.

  • 트랙잭션은 꼭 필요한 최소의 코드에만 사용을 권장. 왜냐면 데이터베이스 커넥션은 개수가 제한적인데 각 단위 프로그램이 이 커넥션을 유지하는 시간이 길어질 경우 여유 커넥션이 줄어든다. 어느 순간 커넥션이 부족해져 다른 프로그램들이 기다려야 하는 상황이 생기기 때문.

🔐Lock(락)은 뭐에요?🔐

락은 데이터의 일관성을 보장해주기 위한 방법이다.

Lock 과 트랜젝션

락과 트랜젝션은 비슷해보이지만 사실 락은 동시성(Concurrency – 동시에 실행되는 것 같이 보이는 것. 싱글 코어에서 멀티 쓰레드를 동작 시키는 방식이다. 한번에 많은 것을 처리하며 논리적인 개념이 되시겠다.)을 제어하기 위한 기능.
트랜젝션은 데이터의 정합성(어떤 데이터들의 값이 서로 일치함.)을 보장하기 위한 것이다.

락은 여러 연결에서 동시에 동일한 자원(여기에선 테이블이나 레코드를 말한다)을 요청할 경우 순서대로 한 시점에는 하나의 연결만 변경할 수 있게 해주는 역할을 한다.

(비유가 맞을지 모르겠지만 밥달라고 여러 마리의 아기 새들이 동시에 어미 새에게 입을 벌리는 것처럼 생각하면 된다. 어미새는 부리가 한 개라 한마리의 새끼 새에게 먹이를 줄 수 있다.)

종류는 두 가지인데 부르는 이름이 여러가지다.

Lock의 종류

🎈 - Shared Lock (공유 락 or Read Lock이라함)
보통 데이터를 읽을 때 사용함. 원하는 데이터에 Lock을 걸었지만 다른 세션에서 읽을 수 있음. 이 Lock을 설정한 경우 추가로 공유Lock을 설정할 수는 있다만 배타적 Lock을 설정할 순 없다(밑에 나온다) -> 내가 보고 있는 데이터는 사용자가 볼 수 있지만 변경은 못한다는 의미다.

🎈 - Exclusive Lock(배타적 Lock Or Write Lock 이라 한다.)
읽기와 반대로 변경할 때 사용한다. 해당 Lock이 해제되기 전까지는 다른 공유 Lock, 배타적 Lock을 설정 할 수 없다. -> 읽기 쓰기가 불가능해진다.

블로킹

이게 불낙이야?

말 그대로 막는다. 막혔다. 이런 의미다. Lock들의 경합이라고도 표현하는데 이것이 발생하면 특정 세션이 작업을 진행하지 못하도 멈춰선다. 공유Lock과 배타적Lock 또는 배타적Lock과 배타적Lock끼리 블로킹이 발생할 수 있다. 이를 해결하는 것은 딱 두 가지 뿐이다.

  1. 트랜젝션 커밋하기.
  2. Rollback 하기.

⚠ 교착상태(Dead Lock) ⚠

다른말로 데드락 이라고 표현한다. 특정 자원의 락을 획득한 채 다른 트랜잭션이 소유하고 있는 락을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태를 뜻한다.
쉽게 풀어쓰면 여기에서 말하는 자원은 테이블 이나 레코드를 뜻한다. 즉 이것에 해당하는 Lock을 가지고 있으면서 다른 트랜잭션의 Lock을 요구하면 뻗어버린다. 아래 그림에 쉽게 나와있다.

이미지 출처

1번 트랜젝션에서 2번 리소스의 Lock을 흭득 하고, 2번 트랜젝션에서는 1번 리소스의 Lock을 획득한 상태다. 이때 동시에 상대방의 데이터에 접근하고자 할때 기존의 Lock이 해제될 때까지 기다리게 되는 상황이라는 뜻이다. (무한 기다림)

이미지 출처

이처럼 1번 트랜젝션이 공유 Lock을 설정하고 슬립(Sleep)모드 였을 때 2번 트랜젝션은 배타적 Lock(Exclusive Lock - (X mode) 배타적 Lock은 여러 트랜잭션이 한 데이터에 접근할 수 없다.)을 설정하려고 한다. 이때 교착상태에 빠진다.

해결 방법은?

  • 트랜잭션을 자주 커밋.
  • 정해진 순서로 테이블에 접근
  • 읽기 잠금 획득(SELECT ~ FOR UPDATE)의 사용을 피하자.
  • 한 테이블의 복수 행을 복수의 연결해서 순서없이 갱신하면 교착상태에 빠지기 쉽다. 그러면 테이블 단위의 잠금을 획득해 갱신을 직렬화하면 동시성이 떨어지지만 적어도 교착상태는 안걸린다.

cs같이 공부하러가기 클릭!


0개의 댓글