2016-08-31 2 views
1

이벤트 코드가 @Transactional annotation으로 주석 된 메서드에 게시 된 코드가 있습니다.@TransactionalEventListener 메서드가 실행되지 않았습니다.

@Override 
@Transactional 
public Task updateStatus(Integer taskId, ExecutionStatus newStatus) { 
    Task task = Task.builder().executionStatus(newStatus).build(); 
    return updateStatusInternal(taskId, rteWithMetadata); 
} 

private TaskExecution updateStatusInternal(Integer taskId, 
     Task newStatus) { 
    Task task = taskService.findById(taskId); 
    TaskExecution te = task.getFirstExecution(); 

    TaskExecution.ExecutionStatus oldStatus = te.getExecutionStatus(); 

    TaskExecution.ExecutionStatus newStatus = newStatus.getExecutionStatus(); 
    log.info(
      "Task Execution status changed. Task id={}, from={}, to={}. Manual override : {}", 
      task.getId(), oldStatus, newStatus, 
      newStatus.isManualOverrideInitiated()); 

    te.setExecutionStatus(newStatus); 

    if (te.getExecutionStatus() == ExecutionStatus.COMPLETED 
      || te.getExecutionStatus() == ExecutionStatus.FAILED) { 
     te.setEndDate(DateTimeHelper.getUtcNow()); 
     if (rte.isManualOverrideInitiated()) { 
      rte.setManualOverrideEndDate(DateTimeHelper.getUtcNow()); 
     } 
    } 

    publisher.publishEvent(TaskStatusChanged.of(task, oldStatus, newStatus)); 
    log.info("Published TaskStatusChanged event. task Id={}", task.getId()); 

    // Send STOMP message 
    final Object payload = StompMessageHelper.getTaskExecutionUpdateMessage(task); 
    messageTemplate.convertAndSend(taskDestination(task), payload); 
    log.info("STOMP message for task status update sent. task Id={}", 
      task.getId()); 

    return te; 
} 

@TransactionalEventListener은 주석 된 애플리케이션 이벤트 리스너 대응 방법이있다.

@Async("changeEventExecutor") 
@TransactionalEventListener(phase=TransactionPhase.AFTER_COMMIT) 
public void taskStatusChanged(final TaskStatusChanged e) { 
    log.info("taskStatusChanged called"); 
} 

문제는 우리의 생산 상자 중 하나에서 발생합니다. 그것은 로컬 dev 환경에서 일관되게 잘 작동하지만 일관되게 생산에 실패합니다.

누가이 문제를 더 빨리 처리 했습니까? 내가 생각할 수있는 유일한 해결책은 수동으로 응용 프로그램 이벤트를 발생시키는 것입니다.

참고 : 기존 게시글을 확인했습니다. 내 시나리오가 기존 게시와 일치하지 않습니다. 내가 생각할 수있는

답변

0

있는 유일한 방법은 Spring's javadoc에서 온다 : 이벤트가 관리 트랜잭션의 경계 내에 게시되지 않습니다

경우 fallbackExecution()가 플래그를 명시 적으로 설정되어 있지 않으면, 이벤트가 삭제됩니다 . 트랜잭션이 실행중인 경우 이벤트는 해당 TransactionPhase에 따라 처리 된 입니다.

트랜잭션이 실행되지 않았습니까? 귀하의 코드 샘플이 완전하지 않다고 가정합니다. 따라서 트랜잭션이 해고 될 때 또는 그 라인을 따라 무언가가 롤백 될 수 있습니다.

@TransactionalEventListener(fallbackExecution=true, phase=TransactionPhase.AFTER_COMMIT) 
+0

''':

어떤 경우

, 당신은 (당신이 생산 상자를 참조 알고, 그래서 일을 시도에 옵션이 무엇인지 확실하지 않다) 다음과 같이 시도해 볼 수도 있습니다 updateStatus'' 메소드는 컨트롤러에 의해 호출됩니다. 왜냐하면'''TransactionStatus''가'''updateStatus''' 메소드에 존재하기 때문에''''updateStatus'''가 호출 될 때 새로운 트랜잭션이 생성 될 것입니다. 이벤트가 트랜잭션 경계 내부에서 시작됩니다. –

+0

전체 updateStatus 메서드를 게시 할 수 있습니까? – alexbt

+0

updateStatus 메소드에 대한 코드가 추가되었습니다. –

관련 문제