Ваша операция состоит из 2 действий:
Получить объект из БД
Сохранить новый объект, если он не существует
Ваша проблема в том, что несколько потоков могут запустить эту операцию одновременно и не видят изменений друг друга.Это определенно не то, что вам нужно.Ваша операция, состоящая из нескольких действий, должна быть атомарной.
Если я правильно понимаю, у вас есть правило хранить только 1 active
продукт того же type
в хранилище данных.Это звучит как требование согласованности данных, которое должно решаться на уровне приложения.
Самый наивный способ решить вашу проблему - это получить блокировку перед выполнением вашей операции.Это может быть решено либо с synchronised
, либо с явной блокировкой:
@Override
public synchronised void save(Product product) {
Product productInDb = productRepository.findOneByTypeAndIsActive(product.getType());
if (productInDb != null)
throw new AlreadyActiveException();
product.setActive(true);
productRepository.saveAndFlush(product);
}