Axon FrameWork: как откатиться в таблице domain_event_entry

Вы можете увидеть мои образцы классов ниже.

По сути, я хочу использовать domain_event_entry таблицу Axon для хранения событий и мою собственную таблицу сущностей для хранения сущностей. Я знаю, что если я запустил CreateTemplateCommand, который обрабатывается в Aggregate, событие будет опубликовано, и что после этого оно перейдет в @EventSourcingHandler, где Axon сохранит событие в своей domain_event_entry таблице.

После этой части он перейдет к моему внешнему @EventHandler, где я хочу сохранить свою сущность из события. Как видите, я бросаю RunTimeException, потому что хочу смоделировать откат. Он откатится в моей собственной таблице, но в domain_event_entry таблице Axon будет событие. Итак, я получу свою таблицу сущностей пустой, а мою таблицу Axon с TemplateCreatedEvent в ней, но я хочу также откатить domain_event_entry.

Как я могу откатить domain_event_entry таблицу или использовать для этого компенсирующие события?

@Aggregate
@Getter
@Setter
@NoArgsConstructor
public class TemplateAggregate {

  private static final transient Logger logger = LoggerFactory.getLogger(TemplateAggregate.class);
  @AggregateIdentifier
  private String templateId;

   private LocalDate createdAt;

   private String createdBy;

   private String description;

   private LocalDate modifiedAt;

   private String modifiedBy;

   private String name;

   private LocalDate validFrom;

   private LocalDate validTo;

   private File file;

   private String fileName;

   private long fileSize;

   private LocalDate fileDate;

   private String fileUploader;

  @CommandHandler
  public TemplateAggregate(CreateTemplateCommand cmd) {
    AggregateLifecycle.apply(new TemplateCreatedEvent(cmd));
  }

  @CommandHandler
  public void handle(ModifyTemplateCommand cmd) {
    AggregateLifecycle.apply(new TemplateModifiedEvent(cmd));
  }

  @EventSourcingHandler
  public void on(TemplateCreatedEvent event) {
    this.templateId = event.getTemplateId();
     this.createdAt = event.getCreatedAt();
     this.createdBy = event.getCreatedBy();
     this.description = event.getDescription();
     this.name = event.getName();
     this.validFrom = event.getValidFrom();
     this.validTo = event.getValidTo();
     this.file = event.getFile();
     this.fileName = event.getFileName();
     this.fileSize = event.getFileSize();
     this.fileDate = event.getFileDate();
     this.fileUploader = event.getFileUploader();
    logger.info("TemplateAggregate - TemplateCreatedEvent");
  }

  @EventSourcingHandler
  public void on(TemplateModifiedEvent event) {
    this.templateId = event.getTemplateId();
     this.createdAt = event.getCreatedAt();
     this.createdBy = event.getCreatedBy();
     this.description = event.getDescription();
     this.name = event.getName();
     this.validFrom = event.getValidFrom();
     this.validTo = event.getValidTo();
     this.file = event.getFile();
     this.fileName = event.getFileName();
     this.fileSize = event.getFileSize();
     this.fileDate = event.getFileDate();
     this.fileUploader = event.getFileUploader();
     this.modifiedAt = event.getModifiedAt();
     this.modifiedBy = event.getModifiedBy();
    logger.info("TemplateAggregate - TemplateModifiedEvent");
  }

}

Мой внешний класс @EventHandler:

@Service
public class TemplateCreatedEventHandler {

  private static final transient Logger logger =
      LoggerFactory.getLogger(TemplateCreatedEventHandler.class);

  @Autowired
  private TemplateRepository templateRepository;

  @Transactional
  @EventHandler
  public void on(TemplateCreatedEvent event) {
    templateRepository.save(new TemplateQueryEntity(event));
    logger.info("EventHandler - TemplateCreatedEvent");
    throw new RuntimeException();
  }



}

person polosoft    schedule 09.09.2019    source источник
comment
Этот пост очень похож на ваш предыдущий: stackoverflow.com/questions/57850894/. Ответ там также уже намекает на решение: использование подписывающегося процессора.   -  person Allard    schedule 09.09.2019


Ответы (1)


Это правильное и ожидаемое поведение обработчика событий отслеживания. Хранилище событий является источником истины, и как только ваше TemplateCreatedEvent сохраняется в хранилище событий, это означает, что «произошло событие, созданное шаблоном».

Ваш обработчик событий по линии не может обработать событие и выдает исключение. Это означает, что транзакция в вашем TemplateCreatedEventHandler откатывается. Это не означает, что история внезапно изменилась; ваш обработчик событий не может решить, что TemplateCreatedEvent не произошло.

Когда вы позже развернете исправление для TemplateCreatedEventHandler, чтобы он мог обрабатывать это событие (удалите RuntimeException), обработчик обработает событие и сохранит сущность.

Если это поведение не то, что вам нужно, вы можете использовать подписывающийся обработчик событий.

SubscribingEventProcessor будет иметь всплывающее окно исключения до компонента публикации события, позволяя ему, соответственно, обрабатывать его.

https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/event-processing/event-processors#exceptions-during-processing

person Mzzl    schedule 09.09.2019