У меня есть приложение JSF / EJB / JPA, которое использует управляемую контейнером персистентность.В одном случае выполняется вызов внешней службы по протоколу HTTP, которая имеет свою стоимость, и эта стоимость возвращается обратно запрашивающему пользователю.В текущей реализации процесс создания HTTP-запроса выполняется методом таймера EJB, периодически запускаемым в фоновом режиме.
Методу таймера может потребоваться обработать несколько запросов в одном вызове, хотя каждый запрос требуетобрабатываться независимо, независимо от распределения затрат обратно пользователю, то естьЕсли у пользователя A недостаточно средств для покупки книги, это не помешает успешной покупке книги пользователем B, в результате чего его баланс будет списан из-за отката.
Для обеспечения контроля надразграничение транзакций для независимой обработки каждого запроса Я использую управляемые компонентом транзакции для класса, в котором находится метод таймера.Это версия java-псевдокода того, что у меня сейчас есть:
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MessageTimer {
private void processMessages(UserMessage msg) {
tx.begin();
em.joinTransaction();
try {
userData = em.find(..., PESSIMISTIC_WRITE);
if(user has enough credit) {
debit cost from user;
status = make external http request to order book from supplier;
if(status == success) {
commit = true;
}
}
} catch(Exception) {
tx.rollback();
}
if(commit) {
tx.commit();
}
else {
tx.rollback();
}
}
}
Итак, идея в том, что я начинаю транзакцию, предполагаю успех и снимаю плату с пользователя, вызываю службу httpи зафиксировать, если это удастся, или выполнить откат в противном случае.
У меня неприятное ощущение, что я не могу быть где-то рядом с правой стадией с этим дизайном, особенно с длительным http-вызовом (фактически сделанным с использованием jax-rs) внутритранзакция pessimistic_write.Мне было интересно, смогу ли я, во-первых, в рамках транзакции дебетовать пользователя (начать / дебетовать / фиксировать), сделать http-вызов, а затем кредитовать пользователя, если произойдет какая-либо ошибка, но нет целостности транзакции.
Это новая территориядля меня, кто-нибудь может указать мне правильное направление, есть ли установленный способ сделать то, что я пытаюсь сделать?
Большое спасибо.
ps Я использую Glassfish 3.1стек со швом 3