본문 바로가기
DB

[DB] 트랜잭션, Lock, ACID, 격리 수준 질문, 답변

by 오렌지마끼야또 2023. 5. 10.
728x90
반응형

 

 

 

 

 

트랜잭션이란 무엇인지 설명해주세요

  • 트랜잭션이란, 데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위를 뜻한다.
  • 상태를 변화시킨다는 것은 SELECT, UPDATE, INSERT, DELETE 와 같은 SQL을 이용해서 데이터베이스에 접근 하는 것을 의미한다.
  • 트랜잭션 하나는 SQL 하나가 될 수도 있고 SQL 여러개가 될 수도 있다.
  • 예를 들어 상품을 구매하는 API가 있다고 하자. 구매를 하기 위한 과정이 1. 유효한 사용자인지 확인, 2. 상품 정보 가져오기, 3. 상품 구매하기 라고 한다면 SQL은 SELECT, SELECT, INSERT가 된다. 이 3개의 SQL이 하나의 트랜잭션이 되는 것이다.

 

https://mommoo.tistory.com/62




트랜잭션과 Lock

  • 멀티 트랙잭션 환경에서 데이터베이스의 일관성과 무결성을 유지하려면 트랜잭션의 순차적 진행을 보장할 수 있는 장치가 필요하다.
  • 예를들어 한명이 도서관의 좌석을 예약하는 중에 다른 한명이 같은 좌석을 예약할 수 없게 하여 한명만 좌석을 배정받을 수 있게한다.

Shared lock (공유 잠금)

  • 한 트랜잭션이 리소스를 읽고 있을 때에는 다른 트랙잭션도 읽을 수는 있지만 변경은 못하게 막는 것.
  • 어떤 트랜잭션에서 데이터를 읽고자 할 때 shared lock은 허용이 되지만 exclusive lock은 불가능하다.
  • 어떤 자원에 shared lock이 동시에 여러개 적용될 수 있다.
  • 어떤 자원에 shared lock이 하나라도 걸려있으면 exclusive lock을 걸 수 없다.

Exclusive lock (배타적 잠금)

  • 한 트랜잭션이 데이터를 변경 중일 때는 완료될 때까지 다른 트랜잭션이 읽거나 변경하지 못하게 막는 것.
  • exclusive lock에 걸리면 shared lock을 걸 수 없다.
  • exclusive lock에 걸린 테이블, row 에 대해 다른 트랜잭션이 exclusive lock을 걸 수 없다.

 

https://velog.io/@haron/DB-Exclusive-lock%EA%B3%BC-Shared-lock%EC%9D%98-%EC%B0%A8%EC%9D%B4#:~:text=Shared%20lock%20(%EA%B3%B5%EC%9C%A0%20%EC%9E%A0%EA%B8%88),-%EC%9D%BD%EA%B8%B0%20%EC%9E%A0%EA%B8%88&text=%EC%96%B4%EB%96%A4%20%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%97%90%EC%84%9C%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC,%EC%9D%84%20%EB%B6%88%EA%B0%80%ED%95%98%EA%B2%8C%20%ED%95%98%EB%8A%94%20%EA%B2%83%EC%9D%B4%EB%8B%A4.



트랜잭션의 특성(ACID)에 대해 설명해주세요

원자성 (Atomicity)

  • 트랜잭션이 DB에 모두 반영되거나, 전혀 반영되지 않거나를 뜻한다.
  • All or Nothing을 생각하면 된다.

일관성 (Consistency)

  • 트랜잭션 작업 처리의 결과가 항상 일관되어야 한다를 뜻한다.
  • 트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트된 데이터베이스로 트랜잭션이 진행되는것이 아니라, 처음에 트랜잭션을 진행 하기 위해 참조한 데이터베이스로 진행된다. 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것이다.

독립성 (Isolation)

  • 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 하나의 트랜잭션은 다른 트랜잭션에 끼어들 수 없다.
  • 즉, 각각의 트랜잭션은 독립적이라 서로 간섭이 불가능하다.
  • 하나의 트랜잭션이 완료될때까지, 다른 트랜잭션이 해당 트랜잭션의 결과를 참조할 수 없다.

지속성 (Durability)

  • 트랜잭션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 함을 뜻한다.
  • 보통 commit 이 된다면 지속성은 만족할 수 있다.





트랜잭션의 상태

트랜잭션은 논리적으로 5가지의 상태에 있을 수 있다.

Active

  • 트랜잭션이 현재 실행 중인 상태

Failed

  • 트랜잭이 실행되다 오류가 발생해서 중단된 상태

Aborted

  • 브랜잭션이 비정상 종료되어 Rollback 이 수행된 상태

Partially Committed

  • 트랜잭션의 연산이 마지막까지 실행되고 Commit이 되기 직전 상태

Committed

  • 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태

 

https://wonit.tistory.com/462




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

  • 트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.
  • 여러 개의 트랜잭션으로 쪼개서 트랜잭션의 범위를 최소화하라는 의미다.
  • 일반적으로 데이터베이스 커넥션의 개수가 제한적이다. 그런데 각 단위 프로그램이 커넥션을 소유하는 시간이 길어지면 사용 가능한 여유 커넥션의 개수는 줄어들게 된다. 이러면 각 단위 프로그램에서 커넥션을 가져가기 위해 기다려야 하는 상황이 발생할 수도 있기 때문이다.

 

https://velog.io/@chldppwls12/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%B4%EB%9E%80

 

 

 

—----------------------------------------------------------------------------------------------------------

 

 

 

트랜잭션 격리 수준

 

Isolation level 필요성

격리 수준(isolation level)이란?

  • 격리수준(isolation level)이란 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 수준입니다.
  • 즉, 한 트랜잭션이 다른 트랜잭션이 변경한 데이터에 대한 접근 강도를 의미합니다.
  • 레벨이 높아질수록 트랜잭션간 고립정도가 높아지며, 성능저하도 야기됩니다.
  • 일반적인 온라인 서비스에서는 READ COMMITTED나 REPEATABLE READ 중 하나를 사용합니다.

필요성

  • 격리수준은 트랜잭션의 ACID 특성을 보장하기 위해서 사용합니다.
  • Locking을 통해 이를 해결할 수 있지만, 무조건적인 Locking은 성능저하를 가져옵니다.
  • 반대로 느슨한 Locking은 데이터 무결성에 큰 문제를 가져옵니다.
  • 효율적인 Locking의 사용을 위해 적절한 격리수준은 반드시 필요합니다.




격리 수준의 종류와 발생하는 동시성 제어 문제

Read Uncommitted (Level 0)

  • 어떤 트랜잭션의 내용이 커밋(Commit)이나 롤백(Rollback)과 상관없이 다른 트랜잭션에서 조회가 가능합니다. 정합성의 문제가 많은 격리 수준이기 때문에 RDBMS 표준에서는 격리수준으로 인정하지 않습니다.
  • Select문이 실행되는 동안 해당 Data에 Shared Lock이 걸리지 않습니다.
  • 이런 이유로 Dirty Read가 발생합니다.



Read Committed (Level 1)

  • 한 트랜잭션의 변경내용이 커밋(Commit)되어야만 다른 트랜잭션에서 조회가 가능합니다. 대부분의 RDBMS에서 기본적으로 사용하는 격리수준입니다.
  • Select문이 실행되는 동안 Shared Lock이 걸립니다. 조회시에는 실제 테이블 값이 아니라 Undo 영역에 백업된 레코드 값을 가져옵니다.
  • 하지만 하나의 트랜잭션에서 똑같은 SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋납니다. 즉, Non-repeatable Read이 발생합니다.




Repeatable Read (Level 2)

  • 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회가 가능합니다. MySQL에서 기본으로 사용하며, 이 격리수준에서는 Non-repeatable Read이 발생하지 않습니다.
  • 트랜잭션이 완료될 때까지 Select문이 사용하는 모든 데이터에 Shared Lack이 걸립니다. 따라서 트랜잭션이 범위 내에서 조회한 데이터의 내용이 항상 동일함을 보장합니다.
  • 트랜잭션이 시작 시점 데이터의 일관성을 보장해야 하기 때문에 트랜잭션의 실행시간이 길어질수록 계속 멀티 버전을 관리해야 하는 단점이 발생합니다.
  • 하지만 Phantom Read가 발생할 수 있습니다.



SERIALIZABLE (Level 3)

  • 가장 단순하면서 엄격한 격리 수준이지만 성능 측면에서는 동시 처리성능이 가장 낮습니다. SERIALIZABLE에서는 PHANTOM READ가 발생하지 않습니다.
  • 트랜잭션들이 동시에 일어나지 않고, 순차적으로 실행되는 것처럼 동작합니다.
  • 하지만, 거의 사용되지 않습니다.

 

https://akasai.space/db/about_isolation/#:~:text=%ED%95%84%EC%9A%94%EC%84%B1,%ED%81%B0%20%EB%AC%B8%EC%A0%9C%EB%A5%BC%20%EA%B0%80%EC%A0%B8%EC%98%B5%EB%8B%88%EB%8B%A4.





동시성 제어로 발생하는 문제

갱신내용 손실

  • 틀내잭션들이 동일 데이터를 동시에 수정할 경우 발생
  • 이전 트랜잭션이 데이터를 수정한 후 트랜잭션을 종료하기 전에 나중 트랜잭션이 수정 값을 덮어쓰는 경우 발생

현황파악 오류

  • 트랜잭션의 중간 수행 결과를 다른 트랜잭션이 참조하여 발생

모순성

  • 여러 사용자가 동시에 데이터를 수정하여 DB내의 데이터들이 서로 일치하지 않거나 출력된 정보가 달라 모순이 나타나는 것

연쇄복귀 불가

  • 여러 트랜잭션이 데이터 공유 시 특정 트랜잭션이 처리를 취소하고자 할 때, 다른 트랜잭션이 처리한 부분에 대해서는 취소 불가할 때 발생

 

https://itpenote.tistory.com/619




낮은 단계 Isolation Level을 활용할 때 발생하는 현상들

Dirty Read

  • 커밋되지 않은 수정중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생하는 현상
  • 어떤 트랜잭션에서 아직 실행이 끝나지 않은 다른 트랜잭션에 의한 변경사항을 보게되는 경우
  • 발생 Level : Read Uncommitted

Non-Repeatable Read

  • 한 트랜잭션에서 같은 쿼리를 두 번 수행할 때 그 사이에 다른 트랜잭션 값을 수정 또는 삭제하면서 두 쿼리의 결과가 상이하게 나타나는 일관성이 깨진 현상
  • 발생 Level : Read Committed, Read Uncommitted

Phantom Read

  • 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽었을 때, 첫번째 쿼리에서 없던 레코드가 두번째 쿼리에서 나타나는 현상
  • 트랜잭션 도중 새로운 레코드 삽입을 허용하기 때문에 나타나는 현상임
  • 발생 Level : Repeatable Read, Read Committed, Read Uncommitted

 

728x90
반응형

댓글