복수의 쿼리 통합
복수의 쿼리를 연속적으로 사용해 일관성 있는 형태의 한 단위
: 갱신은 복수 쿼리가 연속적으로 수행되는 경우가 많다
: 갱신 전의 데이터에 SELECT 사용할 때, 복수 쿼리를 일관된 형태의 덩러리로 다뤄야 한다
MySQL 구조
(1) MyISAM형 : 트랜잭션 사용 불가능한 단순 구조
(2) InnoDB형 : 트랜잭션 사용 가능
트랜잭션의 ACID 특성
ANSI 격리 수준
: 직렬화 기능으로부터 격리 수준을 완화해 자신이 아닌 다른 트랜잭션 영향을 허용
(1) 커밋되지 않은 읽기
(2) 커밋 된 읽기
(3) 반복 읽기
(4) 직렬화 가능
: 격리 수준의 완화에 따라 다음과 같은 현상 발생
(1) 더티 읽기 : 트랜잭션이 커밋되기 전 다른 트랜잭션에서 데이터를 읽는 것
(2) 애매한 읽기 : 트랜잭션이 이전에 읽은 데이터를 닷시 읽을 때, 2회 이후의 결과가 1회때와 다른 현상
(3) 팬텀 읽기 : 트랜잭션을 읽을 때 선택할 수 있는 데이터가 나타나거나 사라지는 현상
InnoDB형 MySQL은 MVCC를 사용한다.
반복 읽기 (RR)
: 기본값
: 최초 쿼리 실행한 시점에 커밋된 데이터를 읽어들인다.
: 복수 회의 쿼리 실행 사이에 다른 트랜잭션이 커밋하더라도, 그 내용은 반영되지 않는다.
커밋된 읽기
: 쿼리를 실행한 시점에서 커밋된 데이터를 읽어들인다.
: 같은 쿼리 복수 실행할 때, 다른 트랜잭션에서 커밋할 경우 최신 쿼리 실행 개시 시점에서 커밋된 데이터를 읽는다.
갱신을 수행하는 트랜잭션 자신
: 트랜잭션 격리 수준이나 COMMIT/ROLLBACK에 관계 없이 자신이 수행한 갱신을 즉시 확인 가능
커밋되지 않은 읽기가 사용되지 않는 이유
: 읽기가 블록되는 경우가 없기 때문에, 커밋되지 않은 읽기가 필요하지 않다.
잠금 타임아웃
: 갱신과 갱신이 부딪치는 경우, 나중에 온 갱신은 잠금 대기 상태가 된다.
: 이때, 잠금 해제를 기다리는 쪽은 잠금을 기다릴 때 어느 정도를 기다릴지 설정할 수 있다.
: innodb_lock_wait_timeout 사용
잠금 대기로 타임아웃 발생하는 경우, DBMS 롤백 단위 다른 경우 존재 가능
: 해당 트랜잭션 전체를 롤백하는 경우 vs 쿼리만 롤백하는 경우
: MySQL의 기본 롤백은 오류가 발생한 쿼리이며, 트랜잭션 전체를 롤백하고 싶다면
- 타임아웃 오류 후 명시적으로 ROLLBACK 실행
- innodb_rollbak_on_timeoutt 시스템 변수 설정
교착 상태
: 트랜잭션 A와 트랜잭션 B가 서로 다른 테이블의 잠금을 얻었을 때,
잠금을 유지한 채 서로 잠금을 건 자원에 잠금이 필요한 처리를 실행해서 아무리 기다려도 상황이 바뀌지 않는 상태.
: OS에서 본 그 친구
교착상태 빈도를 낮추는 대책
교착상태의 확인
: 클라이언트에서 롤백된 트랜잭션의 오류, 서버에서 오류 로그나 명령으로 확인 가능
: 상한 횟수를 정한 재시도 등의 처리나 트랜잭션 재실행 등으로 트러블을 해결해야 한다
오토커밋
: 쿼리 단위로 커밋하는 설정. MySQL의 연결 기본값
: 애플리케이션 잠금 실행하는 경우 커밋 부하가 너무 높다!
적절한 단위와 트랜잭션 격리 수준을 이용해 오토커밋을 피해야 한다
긴 트랜잭션
: 데이터베이스 트랜잭션의 동시성이나 자원의 유횻성을 저하한다.
: 잠금과 블록 사이에 교차가 발생하면 교착 상태가 되고, 긴 트랜잭션 중 하나가 롤백될 수 있다.
(1) 교착상태 빈도를 낮추는 방안 사용
(2) 대량 처리를 적당한 여러개의 트랜잭션으로 나눠서 실행한다.
(3) 아무것도 하지 않는 트랜잭션을 유의한다
(4) 트랜잭션 중 대화 처리를 넣는다 : 불명확한 처리를 포함하지 않도록한다.
(5) 처리 능력 이상의 트랜잭션 수 : 최적의 트랜잭션 수를 부하 실험을 수행해 측정하여 조절한다.