在@EventListener或@TransactionalEventListener

时间:2017-06-26 02:55:14

标签: spring

根据文章Better application events in Spring Framework 4.2,我设置了所有相关的类。我的大多数代码都按照需要工作,但在侦听器的方法中有例外。

控制器:

@PostMapping("/Foos")
public ResponseEntity<Foo> handle(@RequestBody Foo foo){
    Optional<Foo> f = fooService.save(foo);
    return f.isPresent() ?  new ResponseEntity<>(f, HttpStatus.OK) :
            new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

服务:

@Transactional
public Optional<Foo> save(Foo foo){
    foo = fooRepository.save(foo);
    publisher.publishEvent(new FooEvent(foo));
    return Optional.of(foo);
}

在上述方法中没有@Transcational,将无法触发以下方法。

听众

@Async
@TransactionalEventListener(condition ="#event.ok", phase = TransactionPhase.AFTER_COMMIT)
public void handle(FooEvent event){
    Product product = new Product(event.getData());
    productService.save(product);
}

ProductService

@Transactional(propagation = Propagation.REQUIRES_NEW)
public Optional<Product> save(Product product){
    product = productRepository.save(product);
    return Optional.of(product);
}

虽然调用了侦听器方法,但产品数据根本没有保存。代码在Spring Boot应用程序BTW中运行。我还没有在网上找到任何相关信息。如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

根据您想要实现的目标,解决方案可能会有所不同:

  1. 如果您想将产品保存在现有交易(您发布活动的地方)的范围内,那么只需将阶段更改为TransactionPhase.BEFORE_COMMIT,您应该做得很好。< / p>

  2. 如果您想在上一个之后的独立交易中保存产品,请在您的句柄方法中添加@Transactional(propagation = Propagation.REQUIRES_NEW),并将所有其他内容保留原样。