728x90
DBMS의 트랜잭션
트랜잭션
- 제일 먼저 DBMS의 전체적인 구조에 대해서 그림을 통해 나타내보기로했다.
- DBMS마다 구조가 다르기는 하지만, 위의 그림처럼 질의 처리기와 저장 시스템로 구분되어진다.
- 데이터베이스 시스템은 보통 비휘발성 저장 장치인 디스크에 데이터를 저장하며 전체 데이터베이스의 일부분을 메인 메모리에 유지한다. DBMS는 데이터를 고정 길이의 페이지로 저장하며, 디스크에서 읽거나 쓸 때에 페이지 단위로 입출력이 이루어진다. 메인 메모리에 유지하는 페이지들을 관리하는 모듈을 보통 페이지 버퍼 관리자 또는 버퍼 관리자라고 부르는데, DBMS의 많은 주요 모듈 중에서 매우 중요한 모듈 중의 하나이다.
- DBMS에서 트랙잭션 관리에 있어서 버퍼 관리자의 버퍼 관리 정책이 매우 중요한 결정을 가져오게 된다. 이 정책에 따라서 트랜잭션의 UNDO 복구와 REDO 복구가 요구되거나 그러지 않게 된다.
UNDO 복구
- 아직 완료되지 않은 트랜잭션이 수정한 페이지들도 디스크에 출력될 수 있으므로, 만약 해당 트랜잭션이 정상적으로 종료할수 없게 된다면 트랜잭션이 수정한 페이지들도 다시 원상 복구되어야한다. 이 때 발생하는 것이 UNDO 복구이다.
- 정책
- STEAL : 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책
- -STEAL : 수정된 페이지들을 최소한 트랜잭션 종료 시점까지는 버퍼를 유지하는 정책
- STEAL 정책은 수정된 페이지가 어떠한 시점에도 디스크에 써질 수 있기 때문에 필연적으로 UNDO 로깅과 복구를 수반하는데, 거의 모든 DBMS가 채택하는 버퍼 관리 정책이다.
REDO 복구
- 커밋한 트랜잭션의 수정은 어떤 경우에돋 유지되어야한다. 이미 커밋한 트랜잭션의 수정을 재반영하는 복구 작업을 REDO 복구라도 한다.
- 정책
- FORCE : 수정했던 모든 페이지를 트랜잭션 커밋 시점에 디스크에 반영하는 정책
- -FORCE : 수정했던 페이지를 트랜잭션 커밋 시점에 디스크에 반영하지 않는 정책
여기서 -FORCE가 커밋 시점에 어떠한 것도 쓰지않는 것은 아니고 로그는 기록하게 된다.
- FORCE 정책을 따르게 된다면 수정된 페이지들이 디스크에 적용이 되므로 REDO 복구는 필요없게 된다. 하지만 -FORCE 정책은 수정된 페이지들이 디스크에 적용이 되지않을수도 있기때문에 REDO 복구가 사용이 되는 것이다. 그래서 거의 모든 DBMS들은 -FORCE 정책을 사용하게 된다.
- 이에 따라 DBMS는 버퍼 관리 정책으로 STEAL과 -FORCE 정책을 채택하여, UNDO, REDO 복구 둘 다 필요로하게 된다.
트랜잭션 관리
UNDO 복구와 REDO 복구에는 기본적으로 로그를 사용하게된다.
로그
- 로그는 로그 레코드의 연속이며 데이터베이스의 모든 갱신 작업을 기록한다. 로그는 안정적 저장 매체에 기록이 된다. 여기서 안정적 저장매체는 어떤 경우에도 절대로 손실이 발생하지 않는 이른바 이상적인 매체를 뜻한다.
- 로그는 덧붙이는 방식으로 기록되며, 각 로그 레코드는 고유의 식별자를 가지게 된다.
@Transactional
해당 클래스의 Bean을 다른 클래스의 Bean에서 호출할 때만 @Transactional 을 인지하고 작동하게 된다. 스프링에서는 내부적으로 AOP를 통해 해당 어노테이션을 인지하여 프록시를 생성하여 트랜잭션을 자동으로 관리하게 된다.
전파레벨
Propagation.REQUIRED (기본값)
@Transcational(propagation = Propagation.REQUIRED)
- 기본적으로 해당 메서드를 호출한 곳에서 별도의 트랜잭션이 설정되어 있지 않았다면 트랜잭션을 새로 시작한다. 만약 호출한 곳에서 이미 트랜잭션이 설정되어 있다면 기존의 트랜잭션 내에서 로직을 실행한다. (동일한 연결 안에서 실행된다) 예외가 발생하면 롤백이 되고 호출한 곳에도 롤백이 전파된다.
기본값 설정 시 실행된 REQUIRED LEVEL
Propagation.REQUIRED_NEW
@Transcational(propagation = Propagation.REQUIRED_NEW)
- 매번 새로운 트랜잭션을 시작한다. 만약 호출한 곳에서 이미 트랜잭션이 설정되어 있다면 기존의 트랜잭션은 대기상태로 두고 자신의 트랜잭션을 실행한다. 새로운 트랜잭션 안에서 예외가 발생해도 호출한 곳에는 롤백이 전파되지 않는다. 즉. 2개의 트랜잭션은 완전히 독립된 별개의 단위로 작동한다.
Propagation.NESTED
@Transcational(propagation = Propagation.NETSTED)
- 기본적은 REQUIRED와 동일하게 작동한다. 중요한 차이점은 SAVEPOINT를 지정한 시점까지 부분 롤백이 가능하다는 것이다. 유의할 점은 데이터베이스가 SAVEPOINT 기능을 지원해야 사용이 가능하다는 것이다 (ex. Oracle)
'Spring' 카테고리의 다른 글
JPA와 Spring Data JPA (0) | 2022.04.24 |
---|---|
Sring Boot + Redis를 이용한 Cachcing (0) | 2022.04.10 |
[JPA] 더티 체킹 (Dirty Checking) (0) | 2022.04.08 |
[JPA] Bulk Insert 적용기 (0) | 2022.01.06 |