트랜잭션
- 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위
- 여러 개의 쿼리를 하나로 묶는 단위
- 특징: ACID - 원자성, 일관성, 독립성, 지속성
원자성
트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았음을 보장함
커밋과 롤백을 통해 데이터의 무결성 보장
커밋
- 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어
- 트랜잭션 단위로 수행됨
- 변경된 내용이 모두 영구적으로 저장되는 것을 말함
롤백
- 트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 일
트랜잭션 전파
여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것
@Service
@Transactional(readOnly=true)
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Transactional
애너테이션을 통해 여러 쿼리 관련 코드들을 하나의 트랜잭션으로 처리함
일관성
허용된 방식으로만 데이터를 변경하는 것
격리성
트랜잭션 수행 시 서로 끼어들지 못하는 것
여러 개의 격리 수준으로 나뉘어 격리성 보장
격리 수준에 따라 발생하는 현상
- 팬텀 리드: 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우
- 반복 가능하지 않은 조회: 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우
- 더티 리드: 한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 행의 데이터를 읽을 수 있을 때 발생
격리 수준
- SERIALIZABLE: 트랜잭션을 순차적으로 진행시키는 것. 여러 트랜잭션이 동시에 같은 행에 접근할 수 없음.
- REPEATABLE_READ: 하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막지만, 새로운 행을 추가하는 것을 막지 않음. MySQL8.0의 innoDB 기본값.
- READ_COMMITTED: 가장 많이 사용되는 격리 수준이며 PostgreSQL, SQL Server, 오라클의 기본값. 커미 완료된 데이터에 대해서만 조회를 허용하지만, 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있음.
- READ_UNCOMMITTED: 하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출되는 문제가 있지만 가장 빠름
지속성
성공적으로 수행된 트랜잭션은 영원히 반영되어야 함 -> 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함을 의미
데이터베이스는 체크섬, 저널링, 롤백 등의 기능을 제공
- 체크섬: 중복 검사의 한 형태로, 오류 정정을 통해 송신된 자료의 무결성을 보호함
- 저널링: 파일 시스템 또는 데이터베이스 시스템에 변경 사항을 반영하기 전에 로깅하는 것
트랜잭션 등 변경 사항에 대한 로그를 남기는 것
무결성
데이터의 정확성, 일관성, 유효성을 유지하는 것
- 개체 무결성: 기본키로 선택된 필드는 빈 값을 허용하지 않음
- 참조 무결성: 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 함
- 고유 무결성: 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우, 그 속성 값은 모두 고유한 값을 가짐
- NULL 무결성: 특정 속성 값에 대해 NULL이 올 수 없다는 조건이 주어진 경우, 그 속성 값은 NULL이 될 수 없음