Spring/Spring 김영한

[Spring DB 1편] (3) 트랜잭션의 이해

민돌v 2022. 10. 28. 10:13
인프런 김영한 - 스프링 DB 1 강의를 듣고 정리한 글 입니다.

 

 

 

목차

  1.  

1. 트랜잭션이란

  • 트랜잭션(Transaction)을 이름 그대로 번역하면 거래라는 뜻입니다.
  • 이것을 풀어 이야기하면, 데이터베이스에서 트랜잭션은 하나의 거래를 안전하게 처리하도록 보장해주는 것을 뜻합니다.

 

모든 작업이 성공해서 데이터베이스에 정상 반영하는 것을 커밋(Commit)이라 하며,

작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 롤백(Rollback)이라고 합니다.


2. 트랜잭션 특징 (ACID)

트랜잭션은 ACID라 하는 4가지 특징을 보장해야합니다.

  1. 원자성 (Actomicity) : 트랜잭션 내에서 실행한 작업들은 마치 하나으 ㅣ작업인 것처럼 모두 성공하거나 모두 실패해야한다.
  2. 일관성 (Consistency) : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야한다.
    • 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야한다.
  3. 격리성(Isolation) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.
    • 예를들어 동시에 같은 데이터를 수정하지 못하도록 해야합니다.
    • 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level)을 선택할 수 있습니다.
  4. 지속성 (Durability) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 합니다.
    • 중간에 시스템에 문제가 발생해도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 합니다.

 

📌 트랜잭션은 원자성, 일관성, 지속성을 보장합니다.

하지만 격리성은 다릅니다. 트랜잭션간에 격리성을 완벽하게 보장하기위해서는 트랜잭션을 거의 순차적으로 실행해야만 합니다.

이렇게 된다면, 동시 처리의 성능이 매우 나빠지므로 ➡️ ANSI 표준은 트랜잯션의 격리 수준을 4단계로 나누어 정의했습니다.


3. 트랜잭션 격리수준 

트랜잭션 격리 수준 - Isolation level

  • READ UNCOMMITED (커밋되지 않은 읽기)      -  Dirty Read
  • READ COMMITED (커밋된 읽기)                      -가장 많이 씀
  • REPEATABLE READ (반복 가능한 읽기)
  • SERIALIZABLE (직렬화 가능)                            - 거의 사용하지 않음

 

1) READ UNCOMMITED란

  • 각 트랜잭션의 변경 내용이 Commit 이나 Rollback 여부에 상관없이 변경 중 다른 트랜잭션(작업) 에 그대로 보여지게 됩니다.
  • Dirty Read - 다른트랜잭션이 수정중인 데이터를 볼 수 있는 현상을 말합니다.
  • 더티리드 현상은, 데이터가 나타났다가 사라졌다하는 현상을 초래할 수 있기 때문에 개발자에게 혼란을 야기시킵니다.

2) READ COMMITED 란

  • 많은 DB 에서 Default 로 사용하는 트랜잭션입니다.
  • 어떠한 트랜잭션에서 데이터를 변경하더라도 커밋이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있기때문에 DirtyRead 가 발생하지 않습니다.
  • 하지만  NON_REPEATABLE READ 부정합 문제가 존재합니다.
    • 하나의 트랜잭션 내에서 동일한 Select 를 날렸을 때 항상 같은결과를 보장해야한다는 정합성
    • A 트랜잭션 작업 중 다른 B 트랜잭션의 커밋이 완료되어 데이터가 변경되면, 변경된 데이터로 Select를 하기 때문에 조회결과가 중간에 바뀌어버립니다.

3) REPEATABLE READ 란

  • 언두(Undo)영역에 백업된 이전 데이터를 통해 트랜잭션 내에서는 동일한 결과를 보여 주도록 보장하여 Non-Repeatable Read 문제를 해결합니다.
  • 하지만 Phantom Read 문제가 발생합니다.
  • Phantom read란, select ~ for update 와 같은 쓰기 잠금을 거는 경우 다른 트랜잭션에 수행한 변경 작업에 의해 레코드가 보였다가 안보였다가 하는 현상을 말합니다.

4) SERIALIZABLE 란

  • 가장 단순하며 엄격한 격리 수준입니다.
  • 그만큼 동시 처리 성능도 다른 트랜잭션 격리 수준보다 떨어집니다.
  • 한 트랜잭션에서 읽고 쓰고있는 레코드는 다른트랜잭션에서 아예 접근할 수 없도록 Lock을 걸어버리는 격리 수준입니다.
  • Serializable 에서는 모든 부정합 문제가 발생하지 않습니다.

 


4. 데이터베이스 연결 구조와 DB 세션

트랜잭션을 더 자세히 이해하기 위해 데이터베이스 서버 연결 구조와 DB 세션에 대해 알아봅니다,

  1. 사용자는 웹 어플리케이션 (WAS) 나 DB 접근 툴 같은 클라이언트를 사용하여 데이터베이스 서버에 접근할 수 있습니다.
  2. 클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게됩니다,
  3. 이때 데이터베이스 서버는 내부에 세션이라는 것을 만듭니다.
  4. 그리고 앞으로 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행합니다,
  5. 세션은 트랜잭션을 시작하고, 커밋 또는 롤백을 통해 트랜잭션을 종료합니다,
  6. 그리고 이후에 새로운 트랜잭션을 다시 시작할 수 있습니다.
  7. 사용자가 커넥션을 닫거나, 또는 DBA가 세션을 강제로 종료하면 세션은 종료됩니다.

 


5. 트랜잭션 정리

원자성

  • 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 합니다.
  • 트랜잭션의 원자성 덕분에 여러 SQL 명령어를 마치 하나의 작업인 것처럼 처리할 수 있습니다.
  • 성공하면 한번에 반영하고, 중간에 실패해도 마치 하나의 작업을 되돌리는 것처럼 간단히 되돌릴 수 있습니다.

오토 커밋

  • 만약 오토 커밋 모드로 동작하는데, 계좌이체 중간에 실패하면 어떻게 될까요?
  • 쿼리를 하나 실행할 때 마다 바로바로 커밋이 되어버리기 때문에 데이터 정합성이 깨지게 됩니다.

트랜잭션 시작

  • 따라서 이런 종류의 작업은 꼭 수동 커밋 모드를 사용해서 수동으로 커밋, 롤백 할 수 있도록 해야합니다.
  • 보통 이렇게 자동 커밋모드에서 수동 커밋 모드로 전환하는 것을 트랜잭션의 시작이라 합니다.