EJB 3 Атрибут транзакции для метода только для чтения - PullRequest
4 голосов
/ 05 августа 2009

У меня есть метод, который возвращает много данных, если я должен использовать @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) для этого метода. Метод выполняет запрос JPA и загружает все содержимое таблицы (около 1000 строк).

Ответы [ 3 ]

3 голосов
/ 21 августа 2009

Клиент для этого метода - это уже в транзакции? Когда вы используете NotSupported, транзакция звонящего будет приостановлена. Если нет, я бы сказал, просто укажите «Никогда» в качестве типа транзакции. Никогда не лучше, так как вызывающие знают, что они не должны вызывать этот метод из транзакции. Более прямой контракт.

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

2 голосов
/ 01 октября 2014

Я бы не согласился, так как редко случается, что пользователь не участвует в транзакции во почти во всех системах. Наилучший подход - использовать NOT SUPPORTED , чтобы транзакция была приостановлена, если вызывающая сторона уже участвует в какой-либо транзакции. НИКОГДА не хлопотно, если у вас нет серии звонков, которые все находятся в области НЕТ СДЕЛКИ. Короче говоря, НЕ ПОДДЕРЖИВАЕТСЯ - это тип, который следует использовать.

0 голосов
/ 01 марта 2019

Насколько я знаю (по крайней мере, так обстоит дело с Hibernate), вы не можете использовать JPA вне транзакции, поскольку жизненный цикл менеджера сущностей связан с жизненным циклом транзакции. Таким образом, фактический метод, который выполняет запрос, должен быть транзакционным.

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

В более сложных системах полезно полностью отделить ваш уровень данных от бизнес-уровня и создать новый набор объектов. Затем ваш метод вызовет запрос JPA, затем использует возвращенные сущности для заполнения объектов вашего бизнес-уровня и возвращает их. Таким образом, вызывающая сторона никогда не сможет заполучить реальные сущности JPA, и вы сможете делать на своем уровне данных то, что вам нужно, поскольку теперь это всего лишь детали реализации. (Черт, вы могли бы изменить вызов базы данных на удаленный вызов API, и вызывающий абонент не должен был бы знать.)

...