본문 바로가기

dev/java 배포

java 배치 소스

반응형

java 배치 소스 이렇게 해야지
 

# DB
oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
oracle.username=hoho
oracle.password=hoho

# 스케줄 (분 단위)
schedule.interval.minute=1

# 동시 프로시저 최대 개수
worker.pool.size=5
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.InputStream;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

public class Main {

    private static final Logger logger = LogManager.getLogger(Main.class);

    private static final Properties props = new Properties();

    private static String URL;
    private static String USER;
    private static String PWD;
    private static int SCHEDULE_MIN;
    private static int WORKER_POOL_SIZE;

    private static ScheduledExecutorService scheduler;
    private static ExecutorService workerPool;

    // ===== 프로시저 관리 =====
    static class ProcTask {
        String name;
        String sql;
        AtomicBoolean running = new AtomicBoolean(false);

        ProcTask(String name, String sql) {
            this.name = name;
            this.sql = sql;
        }
    }

    // ===== 프로시저 목록 =====
    private static final List<ProcTask> PROC_LIST = Arrays.asList(
            new ProcTask("PROC_A", "{ call PROC_DELAY_2MIN() }"),
            new ProcTask("PROC_B", "{ call PROC_DELAY_2MIN_2() }"),
            new ProcTask("PROC_C", "{ call PROC_DELAY_2MIN_3() }")
    );

    public static void main(String[] args) {

        loadProperties();
        initExecutors();

        logger.info("배치 스케줄러 시작 ({}분 주기)", SCHEDULE_MIN);

        scheduler.scheduleAtFixedRate(
                Main::runAllProcedures,
                0,
                SCHEDULE_MIN,
                TimeUnit.MINUTES
        );

        keepAlive();
    }

    // ===== properties 로드 =====
    private static void loadProperties() {
        try (InputStream in = Main.class.getClassLoader().getResourceAsStream("db.properties")) {

            if (in == null) throw new RuntimeException("db.properties 파일 없음");

            props.load(in);

            URL = props.getProperty("oracle.url");
            USER = props.getProperty("oracle.username");
            PWD  = props.getProperty("oracle.password");

            SCHEDULE_MIN = Integer.parseInt(props.getProperty("schedule.interval.minute", "1"));
            WORKER_POOL_SIZE = Integer.parseInt(props.getProperty("worker.pool.size", "5"));

        } catch (Exception e) {
            throw new RuntimeException("db.properties 로드 실패", e);
        }
    }

    private static void initExecutors() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        workerPool = Executors.newFixedThreadPool(WORKER_POOL_SIZE);
    }

    // ===== 스케줄 실행 =====
    private static void runAllProcedures() {

        logger.info("스케줄 실행: {}", LocalDateTime.now());

        for (ProcTask proc : PROC_LIST) {
            workerPool.submit(() -> executeProcedure(proc));
        }
    }

    // ===== 프로시저 실행 =====
    private static void executeProcedure(ProcTask proc) {

        if (!proc.running.compareAndSet(false, true)) {
            logger.warn("프로시저 {} 실행중 → 스킵", proc.name);
            return;
        }

        long start = System.currentTimeMillis();
        logger.info("프로시저 {} 시작", proc.name);

        try (Connection conn = getConnection();
             CallableStatement stmt = conn.prepareCall(proc.sql)) {

            conn.setAutoCommit(true);
            stmt.execute();

            long sec = (System.currentTimeMillis() - start) / 1000;
            logger.info("프로시저 {} 완료 ({}초)", proc.name, sec);

        } catch (Exception e) {
            logger.error("프로시저 {} 실패", proc.name, e);
        } finally {
            proc.running.set(false);
        }
    }

    private static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USER, PWD);
    }

    private static void keepAlive() {
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException ignored) {}
    }
}

 

반응형

'dev > java 배포' 카테고리의 다른 글

java 실행 jar 배포 에러 #011  (0) 2025.05.08
java batch scheduler #010  (0) 2025.05.06
java Mssql to Oracle #009  (0) 2025.05.06
java mssql to file #008  (0) 2025.05.06
java file read db 저장 #007  (0) 2025.05.01