我有一个代码,其中事件发布在使用Spring @Transactional
注释注释的方法中。
@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");
}
问题是我们的一个生产箱上没有触发监听器。它在本地开发环境中运行良好,但在生产中始终如一。
之前有人面对过这个问题吗?我能想到的唯一解决方案是手动触发应用程序事件。
注意:我已检查过现有的类似帖子。我的方案与任何现有帖子都不匹配。
答案 0 :(得分:0)
我能想到的唯一事情来自Spring's javadoc:
如果事件未在托管的边界内发布 事务,除非fallbackExecution()被丢弃 标志是明确设置的。如果事务正在运行,则事件为 根据其TransactionPhase进行处理。
可能没有正在运行的交易吗?我假设您的代码示例不完整,因此可能在事件被触发时回滚事务或者沿着这些事情回滚。
在任何情况下,您都可以尝试使用以下内容(我知道您指的是一个生产框,所以我不确定您在尝试时有什么选择):
@TransactionalEventListener(fallbackExecution=true, phase=TransactionPhase.AFTER_COMMIT)