개발/Java

이전에 진행한 작업에 대한 복구 로직 구현

haloper 2016. 2. 12. 06:17

프로젝트 진행 중 여러 외부장비에 명령을 전송해야 하는 이슈가 있었습니다.

Request 호출 시 순차적으로 외부장비의 API를 호출하는 방식이었습니다.

문제는 외부 장비들도 서로 통신을 하기 때문에

연속된 요청을 하나의 트랜잭션 처럼 동작 시켜야만 했습니다.


필요한 로직은 아래와 같습니다.


A, B, ... Z 장비들에게 순차적으로 작업을 요청하며,

각 작업 요청 시 마다 성공 여부를 전달받아

성공일 경우에만 다음 작업을 시작합니다.


단, 특정 작업이 실패했을 경우

이전에 진행되었던 모든 작업에 대한 복구 로직이 실행되어야 합니다.

복구 로직을 실행시키기 위해서는

모든 작업 성공 시, 필요한 복구 작업을 등록해 주어야 할 필요가 있습니다.


위와 같은 프로세스를 구현하기 위해

아래와 같은 방식으로 코드를 작성하였습니다.

//RecoveryService.java
import java.util.Stack;

public class RecoveryService {
	private final Stack<recoveryjob> jobStack = new Stack<recoveryjob>();

	// 각 작업 성공 시마다 복구 작업을 push함
	public RecoveryJob push(RecoveryJob recoveryJob) {
		return jobStack.push(recoveryJob);
	}

	// 오류 발생 시 stack에 등록한 모든 복구 작업 실행
	public void recovery() {
		while (!jobStack.isEmpty()) {
			jobStack.pop().recovery();
		}
	}
}

class JobA implements RecoveryJob {

	private int value;

	// A작업 복구 시 필요한 정보 저장
	public JobA(int value) {
		this.value = value;
	}

	// 복구 로직 등록
	public void recovery() {
		System.out.println("A 작업 복구 처리 : " + value);
	}
}

class JobB implements RecoveryJob {

	private String code;

	// B작업 복구 시 필요한 정보 저장
	public JobB(String code) {
		this.code = code;
	}

	// 복구 로직 등록
	public void recovery() {
		System.out.println("B 작업 복구 처리 : " + code);
	}
}

interface RecoveryJob {

	public void recovery();

}
//RecoveryServiceTest.java
public class RecoveryServiceTest {
	
	public static void main(String[] args) {
		RecoveryService recovery = new RecoveryService();
		
		System.out.println("작업 A 완료");
        //A 작업 진행 후
        recovery.push(new JobA(777));
        
        System.out.println("작업 B 완료");
        //B 작업 진행 후
        recovery.push(new JobB("hello"));
   
        //오류 발생 시
        System.out.println("작업 C 진행 중 오류");
        recovery.recovery();
	}
}


실행 결과는 다음과 같습니다.

작업 A 완료

작업 B 진행

작업 C 진행 중 오류

B 작업 복구 처리 : hello

A 작업 복구 처리 : 777