티스토리 뷰
PersistStateMachineHandler에 대한 설명
PersistStateMachineHandler는 Spring State Machine에서 상태를 영속화(Persist)할 수 있도록 도와주는 유틸리티 클래스입니다. 일반적으로 데이터베이스 또는 다른 저장소에 현재 상태를 저장하고, 이후 상태를 복원하거나 변경할 때 유용하게 사용됩니다.
1. PersistStateMachineHandler의 역할
Spring State Machine은 기본적으로 상태를 메모리에 저장합니다. 하지만 애플리케이션이 재시작되거나 세션이 만료되면 상태가 초기화됩니다. 이를 방지하고 상태를 유지하려면 상태를 외부 저장소(예: 데이터베이스)에 저장하고 필요할 때 불러와야 합니다.
주요 기능
- 상태 변경 요청을 처리
- 외부에서 상태 변경 요청을 받으면, 이를 StateMachine에 적용할 수 있도록 지원합니다.
- 현재 상태를 저장
- 데이터베이스 또는 다른 저장소에 현재 상태를 저장하여 애플리케이션 재시작 후에도 이전 상태를 복원할 수 있도록 합니다.
- 이전 상태로 복원
- 저장된 상태를 기반으로 상태 머신을 재구성할 수 있습니다.
2. PersistStateMachineHandler 사용 예시
예제 1: 기본적인 PersistStateMachineHandler 설정
@Configuration
public class StateMachinePersistConfig {
@Bean
public PersistStateMachineHandler persistStateMachineHandler(StateMachine<States, Events> stateMachine) {
return new PersistStateMachineHandler(stateMachine);
}
}
설명
- PersistStateMachineHandler는 기존의 StateMachine을 기반으로 생성됩니다.
- @Bean으로 등록하면 다른 서비스에서 이를 주입받아 사용할 수 있습니다.
예제 2: 상태 변경 요청 처리
@Service
public class OrderStateService {
private final PersistStateMachineHandler persistStateMachineHandler;
@Autowired
public OrderStateService(PersistStateMachineHandler persistStateMachineHandler) {
this.persistStateMachineHandler = persistStateMachineHandler;
}
public boolean changeState(String orderId, States targetState) {
return persistStateMachineHandler.handleEventWithState(
MessageBuilder.withPayload(Events.EVENT1).build(), targetState);
}
}
설명
- handleEventWithState() 메서드를 사용하여 특정 상태(targetState)로 변경할 수 있습니다.
- 상태 변경 시 Message<Events>를 전달하여 이벤트 기반으로 상태 전이를 수행합니다.
예제 3: 데이터베이스를 활용한 상태 저장 및 복원
@Repository
public class OrderStateRepository {
private final Map<String, String> stateStore = new HashMap<>();
public void saveState(String orderId, String state) {
stateStore.put(orderId, state);
}
public String getState(String orderId) {
return stateStore.getOrDefault(orderId, "STATE1");
}
}
@Service
public class OrderStateService {
private final PersistStateMachineHandler persistStateMachineHandler;
private final OrderStateRepository orderStateRepository;
@Autowired
public OrderStateService(PersistStateMachineHandler persistStateMachineHandler,
OrderStateRepository orderStateRepository) {
this.persistStateMachineHandler = persistStateMachineHandler;
this.orderStateRepository = orderStateRepository;
}
public boolean changeState(String orderId, Events event) {
String currentState = orderStateRepository.getState(orderId);
States targetState = States.valueOf(currentState);
boolean success = persistStateMachineHandler.handleEventWithState(
MessageBuilder.withPayload(event).build(), targetState);
if (success) {
orderStateRepository.saveState(orderId, targetState.name());
}
return success;
}
}
설명
- OrderStateRepository는 상태를 저장하는 간단한 저장소 역할을 합니다. (실제 환경에서는 DB에 저장)
- changeState() 메서드는 저장된 상태를 가져와서 새로운 상태로 변경한 후, 변경된 상태를 다시 저장합니다.
3. PersistStateMachineHandler의 주요 메서드
메서드 설명
handleEventWithState(Message<E> event, S state) | 특정 이벤트와 상태를 기반으로 상태 전이를 수행합니다. |
addPersistStateChangeListener(PersistStateChangeListener listener) | 상태 변경을 감지하는 리스너를 추가합니다. |
4. PersistStateMachineHandler 사용 시 주의점
- 외부 저장소(DB, Redis 등)와 함께 사용해야 합니다.
상태를 유지하려면 반드시 상태 정보를 저장할 수 있는 별도의 저장소를 마련해야 합니다. - 상태 변경이 항상 성공하는 것은 아닙니다.
handleEventWithState() 메서드는 boolean 값을 반환하므로, 상태 변경이 실패할 가능성이 있음을 고려해야 합니다. - 멀티스레드 환경에서의 동기화 문제
- 여러 요청이 동시에 들어올 경우, 동일한 엔티티의 상태가 충돌할 수 있습니다.
- 이를 방지하기 위해 락을 걸거나 트랜잭션을 활용하는 것이 좋습니다.
5. 요약
- PersistStateMachineHandler는 상태 머신의 상태를 외부 저장소(DB, Redis 등)에 저장하고 복원할 수 있도록 도와주는 유틸리티입니다.
- handleEventWithState() 메서드를 사용하여 특정 상태에서 이벤트를 처리하고 상태를 변경할 수 있습니다.
- 데이터베이스나 별도의 저장소와 함께 사용해야 실질적인 상태 영속화 기능을 구현할 수 있습니다.
- addPersistStateChangeListener()를 활용하면 상태 변경 이벤트를 감지하여 추가적인 처리를 할 수 있습니다.