Подтвердить что ты не робот

Entitymanager.flush() VS EntityManager.getTransaction(). Commit - что я должен предпочесть?

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

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    employee.getPeriod().setEndDate(endDate);
    em.flush();
}

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    em.getTransaction().begin();
    employee.getPeriod().setEndDate(endDate);
    em.getTransaction().commit();
}
4b9b3361

Ответ 1

В первом примере изменения данных отражаются в базе данных после обнаружения флеша, но они все еще находятся в транзакции.

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

Иногда флеш может быть полезен для сохранения данных между текущей транзакцией и затем, наконец, фиксации изменений после этого. Таким образом, вы также можете отменить предыдущие изменения, если после этого возникнет некоторая проблема, например, для пакетной вставки/обновления.

Ответ 2

Вы прочитали javadoc для флеша и фиксации и знаете, что флеш предназначен только для транзакции внутри? Он сбрасывает (но не фиксирует), тогда как фиксация фиксирует данные (очевидно). Они различны; нет "предпочтения". Первый пример неверен и должен привести к исключению при вызове flush (TransactionRequiredException)

Ответ 3

Оба из ваших образцов кода не сохраняются или не объединяют состояние объекта, которое должно быть записано в DB.

Я не считаю целесообразным сравнивать EntityManager.flush() и EnityManager.EntityTransaction.commit().

flush() ДОЛЖЕН быть заключен в контексте транзакции, и вам не нужно делать это явно, если это необходимо (в редких случаях), когда EntityTransaction.commit() делает это для вас.

Ссылка на эту ссылку Нужно ли в этой ситуации вызывать флеш() (интерфейс JPA)?

Обратитесь к этой ссылке Вопрос о том, как очистить JPA до того, как будет вызван запрос, для сценария использования flush()

Ответ 4

Я бы пошел по сделке, управляемой контейнером, когда это было возможно. Bean управляемые транзакции обычно требуют значительно большего количества кода из-за возможностей Exception. Кроме того, это больше подвержено ошибкам (откаты, управление ресурсами).

Тем не менее, я использовал бы флеш после фиксации в режиме управляемого контейнером. Таким образом, я могу уловить возможные PersistenceExceptions в моем модуле хранения и преобразовать его в более значимое исключение для моего модуля использования. Это потому, что я не хочу обрабатывать исключения для хранилища здесь, потому что я могу заменить модуль хранения на то, что не использует JPA..., который никогда не случался со мной:)

Ответ 5

Я думаю, что недостающая часть, flush() просто добавляет к источникам данных, чтобы быть готовыми к фиксации, дает фактические идентификаторы, но не сохраняется по умолчанию.

Итак, если вам нужно, чтобы flush() работал как commit(), вам нужно установить режим очистки для Commit в EntityManager с помощью:

void setFlushMode(FlushModeType flushMode)
Set the flush mode that applies to all objects contained in the persistence context.

Обратите внимание, что FlushModeType представляет собой перечисление с двумя этими значениями:

FlushModeType AUTO (по умолчанию) Поток выполняется при выполнении запроса. Поскольку: JPA 1.0 FlushModeType COMMIT Промывка происходит при транзакции совершить. Провайдер может выполнять сброс в другое время, но не требуется. Поскольку: JPA 1.0

Я надеюсь, что эта помощь