Граница транзакции, управляемой контейнером, в SFSB

Я прочитал в книге, что:

Обычно контейнер начинает транзакцию непосредственно перед запуском метода корпоративного компонента. Он фиксирует транзакцию непосредственно перед выходом из метода.

Предположим, что мой EJB с отслеживанием состояния выставил 3 бизнес-метода, и клиент вызывает эти 3 метода последовательно и хочет запустить эти 3 метода в рамках одной транзакции. Эти методы будут вызываться для нескольких запросов.

Теперь спецификация говорит, что транзакция фиксируется непосредственно перед выходом из метода. Как я смогу откатить всю транзакцию, если мой 1-й метод успешен, а 2-й (или 3-й) метод не работает?

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

Любая помощь или указатель в правильном направлении будут высоко оценены.


person user2306993    schedule 01.08.2013    source источник


Ответы (2)


Вы используете сессионный компонент с отслеживанием состояния в качестве буфера. И вы хотите транзакцию вокруг нескольких вызовов.

С точки зрения дизайна это нормально, если транзакция запускается и фиксируется/откатывается из одного запроса (например, из одного HttpServletRequest). В этом случае вы можете использовать UserTransaction, чтобы разделить транзакцию на несколько вызовов EJB. Но UserTransaction привязан к текущему потоку, поэтому может быть сложно передать его следующему запросу.

Если вы начинаете и фиксируете из других запросов, вы теряете контроль над длительностью транзакции: теперь транзакцией управляет клиент. Если этот клиент выйдет из строя, транзакция не будет отменена до тех пор, пока не будет достигнуто время ожидания транзакции. Таким образом, в этом случае рекомендуется буферизовать, например, HttpSession. Если все данные собраны, вызовите EJB (без сохранения состояния), чтобы сохранить их.

person Beryllium    schedule 01.08.2013
comment
Спасибо за подробности. Хотя я не хотел использовать UserTransaction, похоже, у меня не осталось другого выбора. - person user2306993; 01.08.2013

Создайте метод в bean-компоненте, который вызывает все остальные 3 метода. Тогда они будут в одной транзакции.

person Kayaman    schedule 01.08.2013
comment
Я могу это сделать, но дело в том, что этот метод будет вызываться для нескольких запросов. - person user2306993; 01.08.2013
comment
@user2306993 user2306993 Что касается нескольких запросов: это меняет вопрос / ответ, я добавил его к вашему вопросу. - person Beryllium; 01.08.2013
comment
@Бериллий, спасибо. Есть ли способ, с помощью которого я мог бы сообщить контейнеру, что он начнет транзакцию так же, как вы, но зафиксирует данные, только если я скажу явно? - person user2306993; 01.08.2013
comment
@user2306993 user2306993 Возможно, это работает с использованием UserTransaction. Я разместил ответ. - person Beryllium; 01.08.2013