본문 바로가기
Spring Framework/JPA

Transaction (트랜잭션)

by 도쿠니 2022. 6. 10.

ACID

Atomic (원자성)

  • All or Nothing
  • 하나의 트랜잭션 내에서 이루어지는 모든 작업은 모두 완료되어 Commit되거나 모두 실행되지 않고 Rollback되어야합니다.

Consistency (일관성)

  • 모든 트랜잭션이 종료된 후에는 DB의 제약조건을 모두 지키고 있는 상태가 되어야 합니다.

 

Isolation (격리성)

  • 트랜잭션은 다른 트랜잭션과 독립적으로 동작해야합니다.
  • 하나의 트랜잭션에 다른 트랜잭션이 끼어들면 안됩니다.
  • 현실적으로는 끼어들기도 하는 성능과 안정성의 trade-off 가 있는 특성입니다.

Isolataion Level (트랜잭션의 격리 수준)

  • 동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있는 정도에 관한 Level
  • 아래의 단계는 위에서 아래로 내려갈수록 성능은 떨어지고 격리성을 증가합니다.

 

  • READ UNCOMMITTED
    • 각 트랜잭션에서의 변경 내용을 COMMIT 이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 읽을 수 있습니다.
    • Dirty Read가 발생합니다.
      • 트랜잭션 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있게 되는 현상
    • 정합성에 문제가 많기 때문에 사용하지 않는 것을 권장합니다.

 

  • READ COMMITTED
    • 실제 테이블 값을 가져오는 것이 아니라 Undo 영역에 백업된 레코드에서 값을 가져옵니다. 
    • RDB에서 대부분 기본적으로 사용되고 있는 격리 수준입니다.
    • Dirty Read는 발생하지 않지만 Non-Repeatable Read가 발생합니다.
      • 하나의 트랜잭션 내에서 똑같은 쿼리를 실행하면 항상 같은 결과를 가져와야 하는데 쿼리의 결과가 상이하게 나타나는 현상입니다. 

 

  • REPEATABLE READ
    • 처음으로 SELECT를 수행한 시점의 snapshot을 기록한 뒤 그 이후에는 모든 SELECT 마다 해당 시점을 기준으로 Consistent Read를 수행하여줍니다.
      • Consistent Read란 SELECT 수행 시 현재 DB의 값이 아닌 특정 시점의  커밋된 DB snapshot을 읽어오는 것을 의미합니다.
      • MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 자신의 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽습니다.
        • Undo 공간에 백업에 해두고 실제 레코드 값을 변경합니다.
        • 백업된 데이터는 불필요해지면 주기적으로 삭제됩니다.
        • 백업된 레코드가 많아지면 서버의 처리성능이 떨어질 수 있습니다.
    • 일반적으로 격리수준은 MYSQL InnoDB의 기본 값인 REPEATABLE_READ를 많이 활용합니다.
    • PHANTOM READ가 발생합니다.
      • 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안 보였다가 하는 현상
      • 이를 방지하기 위해서는 쓰기 잠금을 걸어야 합니다.

 

  •  SERIALIZABLE
    • 모든 작업을 하나의 트랜잭션에서 처리하는 것과 같은 가장 높은 수준의 고립성을 가지고 있습니다.
    • 대신, 성능이 좋지 않고 DEADLOCK이 쉽게 걸릴 수 있습니다. 
    • 데이터베이스에서 잘 사용되지 않습니다.

 

Durability (지속성)

  • 트랜잭션 실행으로 인해 데이터에 적용된 변경 사항은 시스템 오류가 발생해도 저장되도록 보장합니다. 
    • DB 저장이 실패하더라도 모든 로그를 모두 남겨서 DB에 순차적으로 모두 반영되도록 합니다.

댓글