트랜잭션
트랜잭션이란
- 트랜잭션은 작업의 완전성을 보장해 주는 것이다.
- 논리적인 작업 셋을 모두 완벽하게 처리하거나
- 처리하지 못할 경우 원 상태로 복구
- 작업의 일부만 적용되는 현상(Partial update)이 발생하지 않게 해주는 기능이다.
트랜잭션, 잠금, 격리 수준
- 잠금(Lock)은 동시성을 제어하기 위한 기능
- 여러 커넥션에서 동시에 동일한 자원(레코드나 테이블)을 요청할 경우, 순서대로 한 시점에는 하나의 커넥션만 변경할 수 있게 해주는 역할
- 트랜잭션은 데이터의 정합성을 보장하기 위한 기능
- 격리 수준은 하나의 트랜잭션 내에서 또는 여러 트랜잭션 간의 작업 내용을 어떻게 공유하고 차단할 것인지를 결정하는 레벨을 의미한다.
MySQL에서의 트랜잭션
트랜잭션을 지원하는 스토리지 엔진
- InnoDB는 트랜잭션을 지원한다.
- MyISAM이나 MEMORY 는 트랜잭션을 지원하지 않는다.
트랜잭션의 논리적인 작업 셋
- 트랜잭션은 논리적인 작업 셋 자체가 100% 적용되거나(COMMIT) 아무것도 적용되지 않아야(ROLLBACK 또는 트랜잭션을 ROLLBACK 시키는 오류 발생) 함을 보장한다.
- 하나의 논리적인 작업 셋에 하나의 쿼리가 있든 두 개 이상의 쿼리가 있든 관계없다.
Partial Update 현상
트랜잭션 관점에서 InnoDB 테이블과MyISAM 테이블의 차이를 살펴본다.
예를 들어, 각 스토리지 엔진에서 다른 PK로 INSERT + 동일한 PK로 INSERT 문을 실행했을 경우를 보자.
- InnoDB의 경우
- 프라이머리 키 중복 오류로 쿼리 실패
- 다른 PK로 INSERT 한 내역도 함께 지워진다. (트랜잭션)
- MyISAM (혹은 MEMORY)의 경우
- 프라이머리 키 중복 오류로 쿼리 실패
- 다른 PK로 INSERT 한 내역은 INSERT된 상태로 남아 있다.
정리하자면,
- InnoDB는 쿼리 중 일부라도 오류가 발생하면 전체를 원 상태로 만든다는 트랜잭션의 원칙대로 INSERT 문장을 실행하기 전 상태로 그대로 복구한다.
- MyISAM 테이블에서 발생하는 이러한 현상을 부분 업데이트(Partial Update)라고 표현한다.
- 부분 업데이트 현상은 테이블 데이터의 정합성을 맞추는데 어려운 문제를 만들어 낸다.
- 이 현상이 발생하면 실패한 쿼리로 인해 남은 레코드를 다시 삭제하는 재처리 작업이 필요할 수 있다.
주의사항
- DBMS의 커넥션과 동일하게 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.
- 일반적으로 데이터베이스 커넥션은 개수가 제한적이어서 각 단위 프로그램이 커넥션을 소유하는 시간이 길어질수록 사용 가능한 여유 커넥션의 개수는 줄어들 것이다.
- 메일 전송이나 FTP 파일 전송 작업 또는 네트워크를 통해 원격 서버와 통신하는 등의 작업은 DBMS의 트랜잭션 내에서 제거하는 것이 좋다.
- 예를 들어 프로그램이 실행되는 동안 메일 서버와 통신할 수 없는 상황이 발생하면 DBMS 서버까지 위험해진다.
- 작업의 성격에 따라 별도의 트랜잭션으로 분리하는 것이 좋다.
- 단순 조회 작업은 별도로 트랜잭션을 사용하지 않아도 된다.
Reference
참고 서적
📔 Real MySQL 8.0