пружинная загрузка, как обращаться с отказоустойчивостью в асинхронном методе? - PullRequest
1 голос
/ 31 мая 2019

Предположим, у меня есть вызывающая программа для распределения работы по нескольким асинхронным задачам:

public class Caller{
    public boolean run() {
        for (int i = 0: i< 100; i++) {
            worker.asyncFindOrCreate(entites[i]);
        }
        return true;
    }

public class Worker{
    @Autowired
    Dao dao;

    @Async
    public E asyncFindOrCreate(User entity) {
        return dao.findByName(entity.getName).elseGet(() -> dao.save(entity));
    }
}

Если у нас есть 2 одинаковых объекта: с синхронизированным методом будет создан первый, а затем будет извлечен второй из существующего объекта; в асинхронном режиме вторые объекты могут пройти findByName и перейти к save, поскольку первый объект еще не был сохранен, в результате чего save второго объекта выдает ошибку уникального идентификатора.

Есть ли способ добавить некоторую механику отказоустойчивости, чтобы иметь некоторые функции, такие как retry и skipAfterRetry, в частности для операций с базой данных.

1 Ответ

0 голосов
/ 01 июня 2019

В этом особом случае вы должны преобразовать ваш массив в карту. Используйте свойство name в качестве ключа, чтобы не было дублированных записей.

Однако, если этот метод также может вызываться несколькими потоками (т. Е. Он находится на веб-сервере) или запущено несколько экземпляров, он все равно не является отказоустойчивым.

В общем, вы должны позволить БД проверить уникальность. Существует не самый безопасный / простой способ сделать это. Поместите метод save в блок try-catch и проверьте / обработайте исключение уникального идентификатора.

...