Весеннее JPA сохранение не всегда выполняется в БД - PullRequest
1 голос
/ 18 апреля 2020

Я использую репозиторий Spring JPA для работы с некоторыми данными в базе данных.

public List<DHData> editDHData(int id, DHData dhData){
    DHEntity e = dhRepository.findById(id).get();
    int val = e.findDHData(dhData.getDec1(),dhData.getDec2());
    if(val >= 0) {
        e.getDHData().get(val).setEval(dhData.getEval());
        System.out.println(val);
        dhRepository.save(e);
    }
    return e.getDHData();
}

По сути, я получаю всю сущность, меняю то, что мне нужно изменить, а затем сохраняю используя JPA. По-видимому, когда я получаю очень быстрые запросы на одну и ту же сущность (мы используем Angular внешний интерфейс, который отправляет этот тип запроса один за другим без тайм-аута), кажется, что он не способен обрабатывать и перезаписывать полученную базу данных. сохранил только последний запрос.

Есть ли способ сделать каждый вызов согласованным, чтобы он выполнялся один за другим и не пропускался?

Пример

Мой DHEntity содержит (вместе с другой информацией) следующие данные, к которым я обращаюсь и изменяю с помощью метода editDHData.

{ "dec1": 1, 
 "dec2": 2, 
 "eval": 0},
{ "dec1": 1, 
 "dec2": 3, 
 "eval": 0},
{ "dec1": 2, 
 "dec2": 3, 
 "eval": 0}

Метод, который я опубликовал выше, выполняется три раза для изменения значений

Первый вызов:

{ "dec1": 1, 
 "dec2": 2, 
 "eval": 0.5}

Второй вызов:

{ "dec1": 1, 
 "dec2": 3, 
 "eval": 1}

Третий вызов:

{ "dec1": 2, 
 "dec2": 3, 
 "eval": 8}

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

    { "dec1": 1, 
     "dec2": 2, 
     "eval": 0},
    { "dec1": 1, 
     "dec2": 3, 
     "eval": 0},
    { "dec1": 2, 
     "dec2": 3, 
     "eval": 8}

Видимо, методы вызываются 3 раза, но только последний сохраняется в базе данных. Есть ли что-то, что я могу сделать над сущностью / репозиторием, чтобы убедиться, что она работает и согласована? База данных PostgreSQL, а внешний интерфейс Angular (но я сомневаюсь, что это актуально). Когда я делаю звонки через Почтальон (конечно, на их выполнение уходит больше времени), он отлично работает.

Кроме того, я подумал, что, возможно, это потому, что метод не является "потокобезопасным". Если каждый вызов выполняется другим потоком, я думаю, что он сначала читает объект как неизмененный, а затем, когда сохраняет, перезаписывает. Мне нужно, чтобы все операции были последовательными и чтобы обеспечить постоянство базы данных (чего не происходит)

1 Ответ

0 голосов
/ 18 апреля 2020

Действительно, ваше внутреннее Spring-приложение является многопоточным и использует поток для каждого запроса, поэтому ваши запросы не обязательно выполняются последовательно.

Как указывал @Shoshi, вам потребуется pessimisti c блокирование обновлений вашей базы данных, чтобы убедиться, что обновления выполняются в том порядке, в котором они получены, и что каждое обновление завершается до того, как будет выполнено следующее.

Однако я бы также более внимательно посмотрел на фронт-энд. Тот факт, что ваш интерфейс посылает поток запросов на обновление для тех же данных, звучит для меня странно. Возможно, было бы лучше объединить изменения во внешнем интерфейсе и затем отправить один запрос на обновление во внутреннюю часть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...