H2 Database는 경량 오픈소스 관계형 데이터베이스(RDBMS)이다.
자바 기반으로 작성되어 있으며 jar 파일 하나만으로 실행할 수 있는 임베디드형 데이터베이스이다.
테스트 환경이나 애플리케이션 내장용으로 많이 사용되며, MySQL이나 PostgreSQL로 마이그레이션하기 전 학습·프로토타입 단계에서 주로 활용된다.
| 구분 | 설명 | 특징 |
|---|---|---|
| Embedded Mode (임베디드 모드) | 애플리케이션 내부에서만 DB 파일 생성 및 접근 | - 단일 애플리케이션 전용- 파일 기반(.mv.db) 저장 - 가장 간단한 방식 |
| Server Mode (서버 모드) | TCP/IP로 외부 접속 가능 | - 여러 애플리케이션/사용자 동시 접근 가능 - MySQL, PostgreSQL과 유사하게 서버-클라이언트 구조 |
| In-Memory Mode (메모리 모드) | 메모리에만 DB 생성 App 종료 시 데이터 소멸 | - 가장 빠름 - 테스트 환경 최적 - 휘발성 데이터베이스 |
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
spring:
datasource:
url: jdbc:h2:mem:testdb # 메모리 DB
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true # 웹 콘솔 활성화
path: /h2-console # 접속 URL: http://localhost:8080/h2-console
jpa:
hibernate:
ddl-auto: update # 자동 테이블 생성 (create, update, validate, none)
show-sql: true
spring:
datasource:
url: jdbc:h2:file:~/testdb driver-class-name: org.h2.Driver # 로컬 파일로 저장 (~/testdb.mv.db)
username: sa
password:
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/testdb
driver-class-name: org.h2.Driver
username: sa
password:
H2 콘솔은 내장 DB인 H2를 웹 브라우저에서 직접 접속해 쿼리 실행과 데이터 조회를 할 수 있게 해주는 관리 도구이다.
설정에서 spring.h2.console.enabled=true 설정 후 http://localhost:8080/h2-consol로 접속 가능하다.
내장 DB(H2, HSQL 등)는 애플리케이션 시작 시 자동으로 schema.sql과 data.sql을 실행해 스키마와 초기 데이터를 구성한다. 운영 DB와 달리 설치 없이 가볍게 테스트용으로 쓰이며, 종료 시 데이터가 사라지는 특성이 있다.
H2 DB의 SQL은 다른 DB와 완벽하게 호환되진 않는다. (MySQL과는 거의 완벽 호환), 이에 따라 DB의 종류가 다른 경우 MODE를 설정하여 SQL 호환성을 향상할수 있도록 옵션이 필요하다.
→ 그럼에도 완벽 호환은 되지 않음으로 최대한 표준 쿼리나 복잡하지 않도록 DDL, DML 작성 권장
datasource:
url: jdbc:h2:mem:blogdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH
driver-class-name: org.h2.Driver
username: sa
password:
배치(Batch)란? 여러 작업(데이터 처리, 집계, 보고서 생성 등)을 사용자의 개입 없이 일정 단위로 모아 대량 처리하는 방식이다. 실시간 처리와 달리 정해진 시간이나 조건에 따라 반복적으로 실행된다.
Spring Batch: Spring 기반의 배치 처리 프레임워크로, 대용량 데이터의 읽기· 가공· 저장을 효율적으로 지원한다. 트랜잭션 관리, 재시도/재시작, 실행 이력 관리 등 배치에 필요한 기능을 내장하고 있다.
스케줄러(Scheduler)는 특정 작업을 시간이나 주기에 맞춰 자동으로 실행하도록 관리하는 시스템이다.
운영체제나 프레임워크에서 제공되며, 반복 작업· 예약 작업을 효율적으로 처리한다.
Spring에서는 @Scheduled, Quartz 같은 도구를 통해 애플리케이션 내부에서 주기적 작업을 실행할 수 있다.
| 분류 | 도구 | 한 줄 요약 | 특징·강점 | 한계·주의 | 권장 시나리오 | 시작 포인트 |
|---|---|---|---|---|---|---|
| 애플리케이션 내 경량 스케줄러 | Spring @Scheduled | 코드 한 줄로 주기 작업 | Spring 통합, 간단한 CRON/고정주기, 프로파일별 on/off 쉬움 | 단일 인스턴스 기준(동시 실행 제어 약함), 이력/재시도/분산 락 부재 | 단순 알림, 캐시 갱신, 로그 청소 등 경량 반복 작업 | @EnableScheduling + @Scheduled(cron="0 0 * * * *") |
| 엔진 기반 강력 스케줄러 | Quartz | Job/Trigger 모델, 영속화·클러스터링 | 분산 실행, 미스파이어 처리, 캘린더 예외, 동적 등록, 이력 관리 | 러닝 커브, 운영 자원(DS/테이블) 필요 | 멀티 인스턴스, 복잡 CRON/캘린더, 재시도·이력 필수 업무 | Spring Boot Starter Quartz, JDBC JobStore |
| 컨테이너 스케줄 | Kubernetes CronJob | 컨테이너를 클러스터에서 주기 실행 | 인프라 표준화, 격리·스케일, 실패 재시도·병렬정책 | 클러스터 의존, 초 단위 미지원(분 단위), 앱 상태 공유 어려움 | 배치/스크립트성 작업, 마이크로서비스/서버리스 스타일 배치 | CronJob 매니페스트(schedule, concurrencyPolicy, backoffLimit) |
| 엔터프라이즈 워크로드 자동화 | IBM Tivoli Workload Scheduler (TWS) | 대규모·이기종 환경 통합 스케줄 | 메인프레임~클라우드 전사 통합, 거버넌스/컴플라이언스 | 상용 비용, 도입·운영 복잡 | 대기업 전사 배치, 이기종/레거시 연동 핵심 | IBM TWS 콘솔/에이전트 도입 |
| 엔터프라이즈 워크로드 자동화 | Control-M (BMC) | 미션 크리티컬 워크로드 오케스트레이션 | 광범위 커넥터, SLA/가시성, 강력한 운영도구 | 상용 비용, 전용 운영 체계 | 금융/통신/제조 대규모 배치·워크플로 | Control-M 서버/에이전트, 커넥터 설정 |
| 데이터 파이프라인 오케스트레이터 | Apache Airflow | DAG로 의존성 있는 작업 흐름 제어 | 스케줄+의존성 관리, 리트라이, UI/모니터링, 생태계 풍부 | 작업은 ‘트리거’일 뿐(실행 엔진 아님), 초 단위 어려움, 운영 필요 | ETL/ELT, ML 파이프라인, 데이터 엔지니어링 | @dag/@task 파이썬 DAG, Executor 선택(Celery/K8s) |
Quartz는 자바 기반의 강력한 스케줄링 라이브러리로, 작업(Job)과 트리거(Trigger) 구조를 사용해 다양한 일정 실행을 지원한다. 클러스터링, 분산 환경, 실행 이력 관리 등 엔터프라이즈 급 기능을 제공한다. Spring Batch와 통합하여 복잡한 예약 작업이나 반복 작업을 안정적으로 처리할 수 있다.
→ Spring Batch 사용시 조합되는 라이브러리, 병행처리나 트랜잭션 관련 기능을 지원한다.
Spring의 @Scheduled는 애플리케이션 내부에서 일정 주기나 특정 시각에 자동으로 작업을 실행할 수 있도록 지원하는 스케줄링 기능으로 단일 배치 스케줄 작업 시 가장 쉽고 빠르게 구현 될 수 있다.
@EnableScheduling
@SpringBootApplication
public class Application {
}
@Component
public class MyScheduler {
// 5초마다 실행
@Scheduled(fixedRate = 5000)
public void task1() {
System.out.println("5초마다 실행: " + LocalDateTime.now());
}
// 이전 실행이 끝난 후 3초 뒤 실행
@Scheduled(fixedDelay = 3000)
public void task2() {
System.out.println("종료 후 3초 뒤 실행: " + LocalDateTime.now());
}
// 앱 시작 후 10초 대기 → 그 뒤 5초마다 실행
@Scheduled(initialDelay = 10000, fixedRate = 5000)
public void task() {
System.out.println("작업 실행 시각: " + LocalDateTime.now());
}
// 매일 오전 9시에 실행
@Scheduled(cron = "0 0 9 * * *")
public void task3() {
System.out.println("매일 9시 실행: " + LocalDateTime.now());
}
}
@Scheduled(fixedDelay = 3000)
| 속성 | 설명 | 예시 코드 | 동작 예시 |
|---|---|---|---|
fixedRate | 이전 실행 시작 시점을 기준으로 일정 간격마다 실행 | @Scheduled(fixedRate = 5000) | 5초마다 실행 (작업이 오래 걸려도 시작 기준으로 주기 유지) |
fixedDelay | 이전 실행 종료 시점을 기준으로 일정 간격마다 실행 | @Scheduled(fixedDelay = 3000) | 작업이 끝난 후 3초 대기 후 다시 실행 |
initialDelay | 애플리케이션 시작 후 최초 실행까지 대기 시간 설정 | @Scheduled(initialDelay = 10000, fixedRate = 5000) | 앱 시작 후 10초 대기 → 이후 5초마다 실행 |
cron | Cron 표현식 기반으로 실행 시간 제어 | @Scheduled(cron = "0 0 9 * * *") | 매일 오전 9시에 실행 |
@Scheduled(cron = "0 0 9 * * *")
초(0-59) 분(0-59) 시(0-23) 일(1-31) 월(1-12) 요일(0-7, 일=0 또는 7)
| 표현식 (Spring) | 주기 설명 | 사용 예 | Quartz 호환 표현식 |
|---|---|---|---|
0/10 * * * * * | 10초마다 | 서버 상태 헬스 체크 | 0/10 * * * * ? |
0 0/5 * * * * | 5분마다 | 캐시 데이터 갱신 | 0 0/5 * * * ? |
0 0 9 * * * | 매일 09:00 | 리포트 메일 발송 | 0 0 9 * * ? |
0 0 0 * * * | 매일 00:00 | 자정 로그 백업/정산 | 0 0 0 * * ? |
0 0 0 1 * * | 매월 1일 00:00 | 월별 통계 생성 | 0 0 0 1 * ? |
0 0 12 * * MON | 매주 월요일 12:00 | 주간 업무 리마인드 | 0 0 12 ? * MON |
0 30 23 * * FRI | 매주 금요일 23:30 | 주간 데이터 마감 | 0 30 23 ? * FRI |
0 0 8 25 12 * | 매년 12/25 08:00 | 크리스마스 알림 | 0 0 8 25 12 ? |