Как правильно сохранять объекты одновременно с использованием Spring Data JPA? - PullRequest
0 голосов
/ 02 ноября 2018

Я думаю, что мог заметить тупиковую ситуацию, пытаясь одновременно сохранить объекты с помощью аннотации @Async.

Я использовал такой компонент, как

@Component
public class AsyncInserter{
    @Autowired
    private PersonRepository repository;

    @Async
    @Transactional
    public CompletableFuture<Boolean> insert(List<Person> persons){

          repository.saveAll(persons);
          repository.flush();
          return CompletableFuture.completedFuture(Boolean.TRUE);
    }

Я звоню из сервисного уровня, который определяется как @Составная часть открытый класс PersonServiceImpl {

      @Autowired
      private AsyncInserter asyncInserter;

      @Transactional
      public void performDBOperation(List<Person> persons){

           deletePersons(/** some criteria */);
            List<List<Person>> subPersonList = Lists.partition(persons, 100);
            subPersonList.forEach(list->{ statuses.add(asyncInserter.insert(list));});

      }

Как вы заметили, у меня есть команды удаления и вставки (по совместительству), которые я хотел полностью атомарные.

Но я заметил, что это удаление, и несколько вставок отправляются, но никогда не фиксируются.

Я думаю, что есть какая-то блокировка, которая мешает, и я могу изолировать ее при работе в параллельных потоках. В соответствии с https://dzone.com/articles/spring-and-threads-transactions, создается впечатление, что при создании нового потока внешняя транзакция не распространяется на вновь созданный поток, и создается новая транзакция.

У этой конструкции, похоже, есть недостаток. Нужно ли мне удалять перед отправкой для вставок? Но как мне добиться атомарной операции, если одна из вставок дает сбой

Я изменил код для запуска удаления и вставки в одном потоке, и он работает, что в любом случае ожидается. Но то, что я заметил, это то, что после вставки записей требуется больше времени для фиксации. Обычно, 12 секунд больше, чтобы зафиксировать 10K записей. Какие огромные накладные расходы? Есть ли способ улучшить это?

Кстати, я использую пул Hikari Connection.

Спасибо

...