在JPA / JTA事务中调用HTTP服务 - 事务完整性

时间:2011-05-26 13:45:24

标签: rest jpa ejb jta bean-managed-transactions

我有一个使用容器管理持久性的JSF / EJB / JPA应用程序。有 一种情况是通过HTTP调用外部服务,这有一个成本,这个 成本被分配回请求用户。在目前的实施中 生成HTTP请求的过程由定期运行的EJB计时器方法执行 在后台。

虽然计时器方法可能必须在一次调用中处理许多请求 每个请求都需要独立处理,与分配有关 回到用户的成本,即。如果用户A没有足够的信用来购买 这本书不会阻止用户B成功购买书籍而导致他们的书籍成功 因回滚而扣除余额。

提供对事务划分的控制,以便对每个事务进行独立处理 请求我使用bean管理的事务为其中的计时器方法的类 驻留。这是我现在所拥有的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();
    }
  }
}

所以我的想法是我开始一项交易,假设成功并从中扣除成本 user,调用http服务并在成功时提交或以其他方式回滚。

我有一种不安的感觉,我可能不会在这个正确的球场附近 设计,尤其是内部冗长的http调用(实际上是使用jax-rs完成) pessimistic_write事务。我想知道我是否可以在交易中首先 借记用户(开始/借记/提交),进行http呼叫,如果有任何错误,则记入用户 发生了,但没有交易完整性。

对我来说这是一个新的领域,任何人都可以指出我正确的方向,是否有 做我想做的事情的既定方式?

非常感谢。

P.S。我正在使用带有Seam 3的glassfish 3.1堆栈

1 个答案:

答案 0 :(得分:0)

我不确定jax-rs通信层是怎么回事。如果通信是单线程的,那么您编写的代码就是一个长时间运行的事务。这可能会使您的应用程序变慢。

我不是技术大师,但我能建议的是 -

记入帐户并在线程上进行jax-rs调用。在这种情况下,在将呼叫发送到远程节点之前将关闭事务。并且它不会是一个长时间运行的事务,因此应用程序将更快。