Мы хотим реализовать некоторую форму двухфазного принятия в контейнере JEE.Наши требования таковы:
Outer Transaction commit/rollback
|-------------------------------------------->|
Inner Transaction
|----->|
Во время длительной транзакции запускается / фиксируется меньшая внутренняя транзакция.Внутренняя транзакция определяется аннотацией.В этом doInner()
некоторые ресурсы в базе данных сохраняются.
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public int doInner() {
...
}
В точке фиксации / отката внешней транзакции эти ресурсы должны быть окончательно заблокированы (коммит) или освобождены (откат).
До сих пор наша идея заключалась в том, чтобыиспользовать события JEE с наблюдателем AFTER_SUCCESS
/ AFTER_FAILURE
.Однако, если событие вызывается изнутри doInner()
, оно, очевидно, связано с контекстом транзакции внутренней транзакции.
Нашим следующим шагом было использование Interceptor
с doInner()
для запуска события.Однако мы обнаружили, что Interceptor
-код выполняется в той же транзакции, что и doInner()
.
Нашим следующим шагом будет определение двух методов bean-компонента, где doInner()
выполняет обработку транзакций, тогда как другой метод bean-компонента вызывает doInner()
и обрабатывает события.Это, однако, имеет очевидный недостаток, заключающийся в том, что прямой вызов doInner()
будет возможен и оставит базу данных в потенциально несовместимом состоянии.
Поэтому у меня следующие вопросы:
- как обычношаблон для выполнения кода в конце окружающей транзакции во время внутренней транзакции?
- Возможно ли связать событие с внешней транзакцией, пока он находится в потоке управления внутренней транзакции?
- Есть ли возможность, при сохранении управляемых контейнером транзакций, программно запускать внутреннюю транзакцию?
- Есть ли возможность поменять объявление перехватчика и транзакции таким образом, что перехватчик не выполняется внутри транзакции метода?