트랜잭션
데이터 베이스에서 하나의 논리적 기능 또는 작업을 위해 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것입니다.
트랜잭션의 성질
원자성(Atomicity)
트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 합니다.
즉, 트랜잭션 내의 모든 작업은 하나의 원자적 작업으로 간주되어야 하며, 트랜잭션 내의 작업 중 하나가 실패하면 전체 트랜잭션이 롤백되어야 합니다.
일관성(Consistency)
트랜잭션을 수행하면 데이터베이스가 일관된 상태로 유지되어야 합니다. 트랜잭션 전후의 데이터 상태가 일관성 있어야 합니다.
독립성(Isolation)
각각의 트랜잭션은 서로 간섭 없이 독립적으로 이루어져야 합니다.
둘 이상의 트랜잭션이 동시 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없습니다.
지속성(Durability)
트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야 한다.
시스템 장애 또는 다른 문제가 발생해도 트랜잭션이 롤백되지 않고 데이터가 유지 되어야 합니다.
트랜잭션 격리레벨
동시에 DB에 접근할 때 그 접근을 어떻게 제어할지에 대한 설정입니다.
4가지의 레벨이 존재합니다.
- READ-UNCOMMITTED
- READ-COMMTTED
- REPEATABLE-READ
- SERIALIZABLE
밑으로 갈수로 격리 레벨(데이터 정합성)이 높아지며 성능이 떨어집니다.
데이터 정합성과 성능이 반비례하므로 케이스에 맞게 잘 선택하여야 합니다.
데이터베이스의 성능상에 이유로 각 제어조건을 완화하기도 합니다.
예로 100개의 요청이 오게 되면 독립성으로 인하여 100개의 요청을 순차적으로 실행해야 하므로 동시성이 매우 떨어집니다.
그래서 트랜잭션 격리레벨 설정을 통해 동시성을 얻을 수 있습니다.
READ-UNCOMMITTED
격리 수준이 가장 낮고 커밋 전의 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 읽는 것 허용합니다.
이러한 격리레벨에서는 Dirty Read 라는 현상이 발생합니다.
A트랜잭션에서 값을 UPDATE 후 커밋 이전에 B트랜잭션에서 값을 조회하여 데이터에 대한 처리를 하는 도중
A트랜잭션에서 롤백을 한다면 B트랜잭션에서는 무효가 된 데이터 값을 읽고 처리를 하기 때문에 문제가 발생합니다.
READ-COMMITTED
커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능합니다..
A트랜잭션에서 값을 UPDATE후 커밋하기 전에 B트랜잭션에서 값을 조회할 경우 UPDATE 전 데이터 값을 조회하고 A트랜잭션에서 커밋 이후에 B트랜잭션에서 변경된 값을 조회할 수 있습니다.
이러한 격리레벨에서는 Non-Repeatable Read 현상이 발생합니다.
B트랜잭션에서 SELECT문을 2번 실행하는데 두 값이 다른 값이 나오는 데이터 불일치 문제가 발생합니다.
즉 같은 트랜잭션 내에서 같은 데이터를 여러 번 조회했을 때 읽어온 데이터가 다른 경우입니다.
REPEATABLE-READ
트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장합니다.(커밋을 완료한 트랜잭션에 한에서 조회 가능)
READ-COMMITTED와 다른 점은 한 트랜잭션이 조회한 데이터는 트랜잭션이 종료될 때까지 다른 트랜잭션이 변경하거나 삭제하는 것을 막습니다.
이러한 격리레벨에서는 Phantom Read 가 발생합니다.
Phantom Read는 Non-Repeatable Read 의 한 종류로 조건이 걸렸든 안 걸렸든 SELECT문을 사용할 때 발생합니다.
조회해 온 결과의 행이 새로 생기거나 없어지는 현상입니다.
SERIALIZABLE
한 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근 불가합니다.
트랜잭션의 ACID 성질이 엄격하게 지켜지나 성능은 가장 떨어집니다.
단순 SLECET 만으로도 트랜잭션이 커밋될 때까지 모든 데이터에 잠금이 설정되어 다른 트랜잭션에서 해당 데이터를 변경할 수 없습니다.