Java에서 Oracle 데이터베이스의 변경 사항을 구독하는 다양한 방법들이 있습니다. 아래는 주요 기술들에 대한 개요와 예제입니다.
- Oracle Advanced Queuing (AQ) 사용하기
Oracle AQ는 메시지 큐 서비스로, 데이터 변경 이벤트를 게시하고 구독할 수 있습니다.
// AQ 예제 코드
import oracle.jdbc.aq.AQDequeueOption;
import oracle.jdbc.aq.AQMessage;
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/orcl", "username", "password");
OracleConnection oracleConn = conn.unwrap(OracleConnection.class);
AQSession session = ((OracleConnection) conn).createAQSession();
AQQueue queue = session.getQueue("QUEUE_OWNER", "QUEUE_NAME");
AQDequeueOption dequeueOpt = new AQDequeueOption();
dequeueOpt.setDequeueMode(AQDequeueOption.DEQUEUE_REMOVE_NO_DATA);
dequeueOpt.setVisibility(AQDequeueOption.VISIBLE_ON_COMMIT);
while (true) {
AQMessage msg = queue.dequeue(dequeueOpt);
System.out.println("메시지 내용: " + msg.getPayloadData());
}
- Change Data Capture (CDC) 활용하기
CDC는 테이블의 데이터 변경 사항을 캡처하는 데 유용합니다.
// CDC API 예제
import oracle.jdbc.dcn.DatabaseChangeRegistration;
Properties prop = new Properties();
prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
DatabaseChangeRegistration dcr = oracleConn.registerDatabaseChangeNotification(prop);
dcr.addListener(new DatabaseChangeListener() {
@Override
public void onDatabaseChangeNotification(DatabaseChangeEvent event) {
System.out.println("변경된 행 정보: " + event.getTableChangeDescription().get(0).getRowChangeDescription());
}
});
PreparedStatement stmt = oracleConn.prepareStatement("SELECT * FROM TARGET_TABLE WHERE ROWNUM < 1");
stmt.execute();
stmt.close();
- Oracle XStream 사용하기 (버전 12c 이상)
XStream은 고성능 데이터 변경 캡처를 제공합니다.
// XStream 예제 코드
import oracle.stream.XStreamLCR;
XStreamIn xstream = XStreamIn.createXStreamIn(oracleConn, new Properties());
xstream.start(new XStreamInAdapter() {
@Override
public void receiveLCR(XStreamLCR lcr) {
System.out.println("변경 로그: " + lcr.getOperationCode());
}
});
- Debezium 같은 제3자 프레임워크 적용하기
Debezium은 Kafka Connect 기반의 데이터 스트리밍 플랫폼입니다.
// Debezium 설정 예제
Map<String, String> config = new HashMap<>();
config.put("connector.class", "io.debezium.connector.oracle.OracleConnector");
config.put("database.server.name", "server1");
config.put("table.whitelist", "SCHEMA.TABLE");
EmbeddedEngine engine = EmbeddedEngine.create()
.using(config)
.notifying(record -> {
System.out.println("데이터 변경: " + record.value());
})
.build();
engine.run();
- Spring Data와 결합하여 사용하기
Spring Data를 사용하면 간단한 설정으로 변경 스트림을 처리할 수 있습니다.
@Configuration
public class OracleCdcConfig {
@Bean
public OracleChangeStream streamService() {
return OracleChangeStream.builder()
.url("jdbc:oracle:thin:@host:port/service")
.username("user")
.password("pass")
.tables(List.of("TABLE_NAME"))
.build();
}
@Bean
public MessageChannel changeChannel() {
return MessageChannels.direct().get();
}
@Bean
public IntegrationFlow flowHandler() {
return IntegrationFlows.from("changeChannel")
.handle(message -> System.out.println("수신된 변경: " + message.getPayload()))
.get();
}
}
- LogMiner 활용하기 (버전 11g 이상)
LogMiner는 데이터베이스 리소스 파일을 분석하여 변경 사항을 추적합니다.
// LogMiner 예제 코드
try (Connection conn = DriverManager.getConnection(url, username, password)) {
Statement stmt = conn.createStatement();
stmt.execute("BEGIN DBMS_LOGMNR.ADD_LOGFILE('/path/to/logfile.arc'); END;");
stmt.execute("BEGIN DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG); END;");
ResultSet rs = stmt.executeQuery("SELECT OPERATION, SQL_REDO FROM V$LOGMNR_CONTENTS");
while (rs.next()) {
System.out.println("작업: " + rs.getString("OPERATION"));
System.out.println("SQL: " + rs.getString("SQL_REDO"));
}
}
주의사항 및 권장사항
- 권한: CDC나 LogMiner 실행 시 특정 권한이 필요합니다.
- 성능 영향: 지속적인 모니터링이 성능에 미칠 영향을 고려해야 합니다.
- 연결 안정성: 네트워크 중단이나 재연결 문제를 대비해야 합니다.
- Oracle 버전: 각 기능은 특정 버전 이상에서만 지원됩니다.
- 리소스 소모: 데이터베이스 부하가 증가할 수 있습니다.
실제 프로젝트에서는 요구 사항과 환경에 맞는 옵션을 선택해야 합니다.