Drive 인덱스를 새로 만들 때 기존 데이터를 지우고 새 파일 목록을 다시 넣는다.
이 작업이 중간에 실패하면
기존 데이터 삭제됨
새 데이터 일부만 저장됨
같은 상태가 될 수 있다.
그래서 인덱스 교체 부분을 트랜잭션으로 묶었다.
transaction.executeWithoutResult(status -> {
jdbc.update("DELETE FROM drive_file_index ...");
for (var file : files) {
jdbc.update("INSERT INTO drive_file_index ...");
}
jdbc.update("UPDATE drive_index_root_state ...");
});
TransactionTemplate은 코드 안에서 직접 트랜잭션 범위를 정할 때 쓴다.
이번 구조에서는 중요한 게 하나 있었다.
FMS API를 호출해서 파일 목록을 가져오는 작업까지 트랜잭션으로 묶지는 않았다.
FMS 원격 조회
→ 트랜잭션 밖
H2 기존 인덱스 삭제
+ 새 인덱스 저장
+ 상태 변경
→ 트랜잭션 안
원격 요청은 오래 걸리거나 실패할 수도 있어서
DB 트랜잭션을 잡은 채 기다리지 않게 했다.
그리고 새 인덱스 저장 중 하나라도 실패하면 전체가 롤백된다.
즉 이번에 쓴 이유는
여러 DB 변경을 전부 성공하거나
전부 취소해야 할 때
→ TransactionTemplate
@Transactional처럼 선언적으로 쓰는 방법도 있지만
트랜잭션이 필요한 구간을 코드에서 명확하게 좁히고 싶을 때 TransactionTemplate을 쓸 수 있다.