Spring Data Repository Save - Как узнать, что данные действительно сохранены? - PullRequest
0 голосов
/ 16 мая 2018

При сохранении данных в базу данных я действительно хочу знать, что сохраняется. Но мое весеннее приложение не выдает ошибку / исключение.

Итак, у меня есть точка останова в приложении прямо перед операцией сохранения myRepository.save(entity). Когда он останавливается на точке останова, я останавливаю службу БД, а затем продолжаю сохранять.

Я не получаю исключения, моя сохраненная сущность, возвращаемая save(), выглядит нормально. Но в БД ничего не сохраняется. Я могу даже сделать myRepository.findOne(id), и он найдет сущность. Откуда я знаю, что это действительно сохранено?

Если база данных выходит из строя до моего метода @Transactional, тогда я получаю ошибки, но не тогда, когда он останавливается в середине метода.

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

repository.save() не обязательно сбрасывает изменения в базу данных.Это будет сделано только тогда, когда:

  • достигнут конец транзакции (= конец метода @Transactional)
  • сделан зависимый вызов (например, когда выначать использовать repository.findAll() или repository.findOne(id))
  • ...

Это упоминается в документации Hibernate , а также транзакционная запись-позади :

Чтобы уменьшить конфликт блокировок в базе данных, физическая транзакция базы данных должна быть максимально короткой.Длинные транзакции базы данных не позволяют вашему приложению масштабироваться до высокой степени одновременной загрузки.Не держите транзакцию базы данных открытой во время работы на уровне конечного пользователя, но открывайте ее после завершения работы на уровне конечного пользователя.Эта концепция называется транзакционной записью.

Это означает, что если ваша база данных не работает в момент сброса изменений, вы должны получить исключение.Однако это может произойти в конце метода, где-то еще, ....

Это также причина, почему иногда бывает трудно отследить, почему произошло исключение, потому что сброс мог быть вызван намного позжечем когда фактическое сохранение происходит в коде.

Вы можете вручную выполнить сброс в базу данных при необходимости, если вы используете методы repository.flush() или repository.saveAndFlush(), но обычно вам не следует этого делать.

0 голосов
/ 16 мая 2018

Решение состояло в том, чтобы обернуть мои вызовы БД myRepository.save(entity) в класс обслуживания или отдельный метод, помеченный @Transactional.

Таким образом, когда метод вызывается с @Transactional, я получаю исключение. Поскольку фиксация выполняется после вызова метода. Спасибо Мария Секар за понимание. Раньше у меня была аннотация @Transactional на контроллере, которая выдала мне ошибку, но у меня не было возможности что-либо с ней сделать.

Итак, решение, упрощенное

В классе контроллера

@RequestMapping(value = "/notification", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Notification saveNotification(@RequestBody Notification notification) {
    Notification savedNotification = null;
    try {
        myService.save(notification);
    } catch (SQLServerException e) {
        throw new CouldNotSaveNotification(e);
    }
    return savedNotification;
}

В классе обслуживания

@Transactional
public save(Notification notification) {
    myRepo.save(notification);
}
0 голосов
/ 16 мая 2018

Все эти операции будут выполняться в памяти, пока не будет вызван коммит. Только после коммита это будет сохранено в соответствующих БД. После фиксации только триггеры, связанные с БД, такие как foriegn key / related stuff, будут вызываться из db, а если выдает ошибку, то выдает другое, ваш репозиторий просто вернет объект-сущность.

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