Я пытаюсь использовать возможности @Async
среды Spring для выполнения простой задачи индексации.
Проблема, с которой я сталкиваюсь, заключается в том, что я чувствую, что EntityManager
используется в моей функции Asyncкаким-то образом используется из предыдущих вызовов, поэтому мои данные не обновляются, а иногда используются старые данные.
Вот код, который я написал в качестве примера. Цель состоит в том, чтобы обновить данные продукта и асинхронно проиндексировать их после публикации события с использованием 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);
}
}
Как вы можете видеть на SlowProcesses файл, если я обновляю объект продукта в entityManager, я получаю правильные и актуальные данные. Если нет, я могу получить старые данные из предыдущих звонков.
Как правильно использовать EntityManager в асинхронном вызове? Мне действительно нужно обновить все мои объекты, чтобы все работало? Я что-то не так делаю?
Спасибо, что прочитали