Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在@Async调用中正确使用EntityManager_Java_Spring_Spring Data - Fatal编程技术网

Java 在@Async调用中正确使用EntityManager

Java 在@Async调用中正确使用EntityManager,java,spring,spring-data,Java,Spring,Spring Data,我试图使用Spring框架的@Async功能来执行简单的索引任务 我面临的问题是,我觉得异步函数中使用的EntityManager以某种方式从以前的调用中重用,因此我的数据不是最新的,有时使用旧数据 下面是我作为示例编写的代码。目标是在使用Spring的ApplicationEventPublisher发布事件后,更新产品数据并对其进行异步索引: 产品服务 @Service class ProductService { private final EntityManager entit

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

我面临的问题是,我觉得异步函数中使用的
EntityManager
以某种方式从以前的调用中重用,因此我的数据不是最新的,有时使用旧数据

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

产品服务

@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());
    }
}
异步进程

@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);
    }
}
@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);
    }
}
慢进程

@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);
    }
}
@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);
    }
}
正如您在SlowProcesses文件中看到的,如果我在entityManager中刷新产品对象,我将获得正确的最新数据。如果没有,我可能会从以前的调用中获取旧数据

在异步调用中使用EntityManager的正确方法是什么?我真的必须刷新所有对象才能使一切正常工作吗?我还做错什么了吗?


感谢您通读

,因为EntityManager的实例并不像Jordie所指出的那样是线程安全的,所以您可以尝试以下方法:

与其注入EntityManager,不如注入EntityManager工厂。然后从EntityManager工厂检索一个新的EntityManager实例,该实例仅在所讨论的方法期间使用。

EntityManager实例不是线程安全的。