Я установил аннотацию TransactionAttribute на ОБЯЗАТЕЛЬНО на уровне класса.Я понимаю, что это означает, что все методы, такие как doSomething (), должны вызываться в предоставленной транзакции.В этом случае мы используем транзакции, управляемые контейнером.
Использование MANDATORY
на уровне класса означает, что контейнер должен выдать исключение вызывающей стороне, если не выполняется транзакция при вызове любого метода FirstEjbType
.
Из любопытства, кто инициирует транзакцию тогда?Есть ли конкретная причина не использовать значение по умолчанию REQUIRED
?
TransactionAttribute вообще не используется в SecondEjbType или ThirdEjbType ... ни на уровне класса, ни на уровне метода.Я понимаю, что это означает, что secondEjb.doSomething () и thirdEjb.doSomething () будут работать в транзакции, предоставленной для firstEjb.doSomething ()
Это означает, что используется атрибут транзакции по умолчанию, т.е.REQUIRED
, и метод REQUIRED
гарантированно будет выполнен внутри транзакции (контейнер запустится один , если потребуется ).
Так что в вашем случае, secondEjb.doSomething()
и thirdEjb.doSomething()
должно быть действительно выполнено в рамках транзакции firstEjb.doSomething()
.
Я пропустил что-то очевидное, или мое концептуальное понимание в основном верно, и проблема может быть в другом месте?
Практическое правило для распространения контекста персистентности (в области транзакции) заключается в том, что контекст персистентности распространяется по мере распространения транзакции JTA.Но есть некоторые ограничения.В спецификации JPA это выглядит следующим образом:
5.6.3 Распространение контекста постоянства
Как описано в разделе 5.1, один контекст постоянства может соответствовать одному или нескольким экземплярам диспетчера сущностей JTA (все связаны с одной и той же фабрикой диспетчера сущностей).
Контекст персистентности распространяется по экземплярам диспетчера сущностей по мере распространения транзакции JTA.
Распространение контекстов персистентности применяется только в пределах местная среда.Контексты постоянства не распространяются на удаленные уровни.
И Sahoo (из команды GlassFish) более подробно пишет о правилах распространения в Распространение контекста постоянства :
3.(правило № 3) Не ожидайте, что компьютер будет распространяться при вызове удаленного EJB, даже если удаленный EJB работает в той же JVM или в том же приложении.
Итак,предполагая, что вы используете JPA везде, я ожидал бы, что бизнес-методы, вызываемые в одной и той же транзакции, наследуют один и тот же контекст постоянства только , если вы не используете Remote
интерфейсы (я не знаю,специфичная интерпретация спецификации GlassFish, но Sahoo довольно ясно об этом ограничении).
PS: JPA предполагает уровень изоляции READ_COMMITTED
(поэтому может работать оптимистическая блокировка), а стандартный JPA не допускает пользовательских настроек уровней изоляции (ну, некоторые провайдеры разрешают изменять его либо глобально, либо по запросу, ноэто непереносимо).
PPS: Я Я не уверен, что уровни изоляции являются ключом к вашей проблеме здесь.
Ссылки
- JPA 1.0 Спецификация
- Раздел 5.6.3 «Распространение контекста постоянства»