2014-02-10 1 views
5

Мы работаем над небольшим веб-интерфейсом (будет работать на Tomcat) с уровнем данных, созданным с помощью JPA (Eclipselink). Я сделал подобную вещь некоторое время назад. Но я всегда был не уверен, когда мне нужно начинать и заканчивать транзакции или делать флеш. В настоящий момент я использую транзакцию, если я добавляю (сохраняю) и удаляю объекты. Если я вызываю сеттеры на уже сохраненном объекте, я не использую транзакции.Приложение, управляемое JPA, когда требуется транзакция

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

ответ

7

Я думаю, что можно суммировать ответ на ваш вопрос. Для любой операции JPA требуется транзакция, кроме find/selects, которая не блокирует объекты (например, любая операция JPA, которая не изменяет данные).

(JTA транзакции Scoped диспетчер объектов) В случае сделки в области видимости управляющего объектом JTA это лучше процитировать спецификации (Глава 3 Entity Операции):

сохраняется, методы слияния, удаления и обновления должны быть вызваны в пределах контекстом транзакции, когда используется диспетчер сущностей с контекстом персистентности транзакций с областью . Если контекст транзакции отсутствует, генерируется исключение javax.persistence.TransactionRequiredException.

Методы, определяющие режим блокировки, отличный от LockModeType.NONE необходимо вызвать в контексте транзакции. Если контекст транзакции отсутствует, генерируется исключение javax.persistence.TransactionRequiredException.

Метод находки (при условии, что вызывается без замка или вызывается с LockModeType.NONE) и метод getReference не требуется, чтобы быть вызван в пределах контекста транзакции. Если используется менеджер сущностей с контекстом персистентности с транзакцией , результирующие объекты будут отсоединены; если используется менеджер сущностей с расширенным контекстом постоянства , они будут управляться. См. Раздел 3.3 для диспетчера сущностей за пределами транзакции.

(Применение управляемого/ресурсов локального диспетчера объектов) В случае управляющего объекта Application управляемого, спецификация JPA не ясно, о поведении. В случае Hibernate довольно сложно, что происходит, когда не внутри транзакции (это может зависеть также от драйвера JDBC и режима автосохранения соединения БД). Проверьте Hibernate's article на эту тему. В основном вам настоятельно рекомендуется всегда использовать транзакции для вышеупомянутых операций.

Во вторую часть вашего вопроса: если вы вызвали средство управления управляемой сущностью и не очистили, вы отделили его (т.е. до совершения транзакции), поведение нечеткое/неопределенное, то есть лучше исправить код ,

Пример багги кода:

//begin Transaction 
MyEntity entity = em.find(MyEntity.class, 1L); 
entity.setField("New value"); 
em.detach();//it is not sure whether the "New value" will be persisted. To make sure it is persisted, ypu need to call em.flush() before detaching 
//commit Transaction 

Обычно, если порядок операций БД (не то же самое, как и порядок менеджера enity операций) не имеет значения, вы можете оставить реализацию JPA, чтобы решить, когда (например, при совершении транзакции).

+0

Так что для сеттеров мне нужен флеш, но мне не нужна операция начала/конца? Но зачем смывать? Поскольку я читаю здесь и там, кажется, что flush опустошает кеш sql-команды (немедленно выполнить все операции), но почему бы не позволить JPA-Реализации решить, когда нужно выполнить? – dermoritz

+0

, так что код в порядке, если не вызван em.detach()? не багги код: MyEntity entity = em.find (MyEntity.class, 1L); entity.setField («Новое значение»); – dermoritz

+0

Да, конечно. Это «обычная ситуация». flush будет вызван автоматически при совершении транзакции :) –