Вызов службы HTTP в транзакции JPA / JTA - целостность транзакции - PullRequest
0 голосов
/ 26 мая 2011

У меня есть приложение 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

1 Ответ

0 голосов
/ 27 мая 2011

Я не уверен, каков уровень связи jax-rs. если связь однопоточная, то написанный вами код является долго выполняющейся транзакцией. что может замедлить работу вашего приложения.

Я не технический гуру, но я могу предложить следующее:

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

...