[DB] 트랜잭션 격리 수준(Transaction Isolation Level)

giggle·2023년 8월 15일
0
post-custom-banner

📌 트랜잭션 격리 수준(Transaction Isolation Level)이란?

트랜잭션에서 일관성 없는 데이터를 허용하도록 하는 수준으로 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 수준입니다.
즉, 여러 개의 트랜잭션이 동시에 실행될 때 어떤 트랜잭션의 변경 내용이 다른 트랜잭션에게 보이는지와 관련된 개념입니다. 이러한 격리수준은 데이터베이스 시스템에서 동시성 제어와 관련하여 어떤 수준의 격리를 보장할지 결정하는 중요한 요소입니다.

📌 필요성

데이터베이스는 ACID 특징과 같이 트랜잭션이 독립적인 수행을 하도록 합니다.

따라서 Locking을 통해, 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하도록 막는 것이 필요합니다.

하지만 무조건 Locking으로 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하는 방식으로 구현하게 되면 데이터베이스의 성능은 떨어지게 될 것입니다.

그렇다고 해서, 성능을 높이기 위해 Locking의 범위를 줄인다면, 잘못된 값이 처리될 문제가 발생하게 됩니다.

-> ❗️ 따라서 최대한 효율적인 Locking 방법이 필요하게 되었습니다.

트랜잭션에서 Locking과 Unlocking은 동시성 제어를 위해 사용되는 개념입니다.

Locking : 트랜잭션이 데이터를 읽거나 수정할 때, 해당 데이터에 잠금을 걸어 다른 트랜잭션이 해당 데이터를 변경하지 못하도록 막는 것을 의미합니다. 데이터에 잠금을 걸어 다른 트랜잭션의 간섭을 방지하여 일관성을 유지합니다.

  • Shared Lock : 다른 트랜잭션은 읽을 수는 있지만, 수정할 수 없는 상태로 데이터에 잠금을 걸어 해당 트랜잭션이 데이터를 사용 중임을 알립니다. 여러 트랜잭션이 동시에 동일한 데이터를 읽을 수 있습니다.

  • Exclusive Lock : 다른 트랜잭션이 해당 데이터를 읽거나 수정할 수 없도록 완전히 잠금을 걸어 다른 트랜잭션의 간섭을 막습니다. 하나의 트랜잭션이 해당 데이터를 사용 중일 때 다른 트랜잭션은 해당 데이터에 접근할 수 없습니다.

Unlocking : 트랜잭션이 데이터 조작을 완료하거나 롤백할 때, 해당 데이터에 걸려있던 잠금을 해제하여 다른 트랜잭션이 해당 데이터에 접근하고 변경할 수 있도록 허용합니다.

📌 종류

Read Uncommitted (레벨 0)

SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리지 않는 계층

  • 트랜잭션에 처리중이거나, 아직 Commit되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용합니다.
  • 즉, 어떤 트랜잭션의 변경 내용이 COMMIT이나 ROLLBACK과 상관없이 다른 트랜잭션에서 보여집니다.
  • 가장 낮은 격리 수준이므로 데이터의 일관성을 유지하는 것이 힘듭니다.

Read Committed (레벨 1)

SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리는 계층

  • 어떤 트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회 가능합니다.
  • 트랜잭션이 수행되는 동안 다른 트랜잭션이 접근할 수 없어 대기하게 됩니다.
  • 대부분의 SQL 서버가 Default로 사용하는 격리 수준

Repeatable Read (레벨 2)

트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층

  • 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회 가능합니다.
  • 트랜잭션이 범위 내에서 조회한 데이터 내용이 항상 동일함을 보장합니다.
  • 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정이 불가능합니다.
  • MySQL에서 Default로 사용하는 격리 수준

Serializable (레벨 3)

트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층

  • 트랜잭션이 특정 테이블을 조회하면 다른 트랜잭션은 그 테이블의 데이터를 추가/변경/삭제 불가능합니다.
  • 완벽한 읽기 일관성 모드를 제공하고, 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력 불가능합니다.

레벨이 높아질수록 트랜잭션 간 고립 정도는 높아지지만 성능이 떨어집니다.

📌 고려사항

Isolation Level에 대한 조정은, 동시성과 데이터 무결성에 연관되어 있습니다.

동시성을 증가시키면 데이터 무결성에 문제가 발생하고, 데이터 무결성을 유지하면 동시성이 떨어지게 되고 레벨을 높게 조정할 수록 발생하는 비용이 증가합니다.

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

Dirty Read

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

Non-Repeatable Read

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

Phantom Read

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

참고


피드백 및 개선점은 댓글을 통해 알려주세요😊

profile
배움을 글로 기록하는 개발자가 되겠습니다.
post-custom-banner

0개의 댓글