TIL - 0810

데이터베이스

트랜잭션과 MySQL

  • 트랜잭션 : 복수 쿼리로 처리해야할 때 하나의 작업으로 묶는 것, 단일 작업으로 만들어내는 것
    • 오토커밋모드와 단일 쿼리 : MySQL, PostgreSQL 등 몇몇 RDBMS는 오토커밋모드가 기본설정인데, 단일 쿼리의 경우 오토커밋 대상
    • COMMIT과 ROLLBACK : 트랜잭션(모든 쿼리) 성공 시 커밋(완료, 저장소 적용), 하나의 쿼리라도 실패 시 롤백(이전 상태로 되돌리기, 저장소 상태 되돌림)
    • CREATE TABLE과 COMMIT : CREATE TABLE(DDL) 쿼리는 바로 커밋(다른 트랜잭션에서 읽을 수 있음)
  • 트랜잭션이 가져야할 특성
    1. 원자성 : 더이상 쪼갤 수 없음, 하나의 작업으로 취급해야함(여러 쿼리라도 하나의 쿼리처럼), 하나라도 실패하면 롤백, 모두 성공하면 커밋처리
    2. 일관성 : 데이터의 무결성을 지켜야함, 개체 무결성(PK- NULL이면 안되고 고유한 값이어야함) , 참조 무결성(FK - 다른 테이블의 데이터를 식별할 키를 가지고 있다면 해당 값은 NULL이던지 존재하는 값이어야함), 데이터 범위 무결성(정의한 범위 내의 값이어야함 - 컬럼 별로)
    3. 격리성 : 데이터베이스는 병렬로 트랜잭션을 처리할 수 있는데, 트랜잭션 간에 간섭이 일어나서는 안됨(트랜잭션 처리 결과가 씹혀서 안됨 - 순서가 어떻게 될지는 모르지만 예상되는 경우의수 범위 내에서 결과값이 나와야함, 그 말은 곧 모든 트랜잭션이 정상적으로 처리되었다는 뜻이므로)
    4. 지속성 : 완료 - 적용(COMMIT)된 작업은 영구적으로 저장되어야함
  • 생각해보아야할 멀티 쓰레드 환경에서의 트랜잭션 처리
    • 객체지향 프로그래밍에서 동시에 처리를 하다보면 발생하는 race-condition, 데이터베이스도 마찬가지 : 객체지향에서 synchronized와 같이 락 방법을 제공한다면 데이터베이스도 락 정책을 제공함 - 기본적으로 데이터베이스가 채택하고 있는 락 정책(격리레벨)이 있음
    • 격리레벨을 높이면(병렬처리쪽) 데아터 무결성이 깨질 수 있고, 격리레벨을 낮추면(직렬처리) 성능상 이슈(순차적으로 처리하려다보니 트랜잭션이 많이 발생할 수록 동일 데이터에 대해 처리 대기가 생기면서)가 생김
  • 격리레벨 완화(직렬보단 병렬)에 따른 현상 : T1, T2 두 개의 트랜잭션이 있다는 가정 하에
    • Dirty Read : T1이 SELECT로 데이터 조회(작업 더 있음), T2가 동일 데이터 조회 - 수정을 한 상태(작업 더 있음), T1이 다시 SELECT 하였을 때 T2의 변경사항을 읽을 수 있게됨
    • Non Repeatable Read : T1이 SELECT로 데이터 조회(작업 더 있음), T2가 동일 데이터 조회 - 수정을 하고 커밋을 함, T1이 다시 SELECT 했을 때 이전 SELECT한 내용과는 다른 T2가 커밋한 내용이 조회가 됨(내용이 다른 것)
    • Phantom Read : T1이 범위 SELECT한 후(작업 더 있음), T2가 범위에 해당할 수 있는 데이터를 INSERT하거나 DELETE 후 COMMIT까지 한 상태에서 T1이 다시 범위 SELECT를 한 경우 처음과 달리 더 늘어난 범위 데이터가 조회되거나 삭제된 상태를 말함(개수가 다른 것)
  • 내일은 격리레벨(Lock policy) 알아보기