java - Java - 在@Async调用中,正确使用EntityManager

我试图使用Spring Framework的@Async功能来执行简单的索引任务。

我所面临的问题是,我的异步函数中使用的EntityManager是从以前的调用中重用的,有时使用旧数据。

下面是我作为例子编写的代码,目标是更新产品的数据,并在使用spring的ApplicationEventPublisher发布事件后,异步地对它进行索引:

ProductService


@Service


class ProductService {



 private final EntityManager entityManager;



 private final ApplicationEventPublisher eventPublisher;



 @Autowired


 public ProductService(EntityManager entityManager, ApplicationEventPublisher eventPublisher) {


 this.entityManager = entityManager;


 this.eventPublisher = eventPublisher;


 }



 @Transactional


 public void patchProduct (String id, ProductDto productDto) {


 Product product = this.entityManager.find(Product.class, id);


 product.setLabel(productDto.getLabel());


 this.entityManager.flush();


 this.eventPublisher.publishEvent(new ProductEvent(product, ProductEvent.EVENT_TYPE.UPDATED));


 }


}



EventListener


@Component


public class ProductEventListener {



 private final AsyncProcesses asyncProcesses;



 @Autowired


 public ProductEventListener (


 AsyncProcesses asyncProcesses


 ) {


 this.asyncProcesses = asyncProcesses;


 }



 @EventListener


 public void indexProduct (ProductEvent productEvent) {


 this.asyncProcesses.indexProduct(productEvent.getProduct().getPok());


 }


}



AsyncProcesses


@Service


public class AsyncProcesses {



 private final SlowProcesses slowProcesses;



 @Autowired


 public AsyncProcesses(SlowProcesses slowProcesses) {


 this.slowProcesses = slowProcesses;


 }



 @Async


 public void indexProduct (String id) {


 this.slowProcesses.indexProduct(id);


 }


}



SlowProcesses


@Service


public class SlowProcesses {



 private EntityManager entityManager;



 private ProductSearchService productSearchService;



 @Autowired


 public SlowProcesses(EntityManager entityManager, NewProductSearchService newProductSearchService) {


 this.entityManager = entityManager;


 this.newProductSearchService = newProductSearchService;


 }



 @Transactional(readonly = true)


 public void indexProduct (String pok) {


 Product product = this.entityManager.find(Product.class, pok);


 // this.entityManager.refresh(product); -> If I uncomment this line, everything works as expected


 this.productSearchService.indexProduct(product);


 }


}



什么是在异步调用中使用EntityManager的正确方法? 我是否必须刷新所有对象才能使所有工作都正常?

时间:

由于EntityManager的实例不是线程安全的,所以这有所帮助:
不要注入EntityManager,而是注入EntityManagerFactory ,然后从EntityManagerFactory检索一个只用于所讨论方法的持续时间的新EntityManager实例。

...